【问题标题】:How to construct Model in MVC - swift如何在 MVC 中构建模型 - swift
【发布时间】:2021-04-06 11:29:03
【问题描述】:

我很困惑,在 MVC 中

模型不应该与view 交谈,但到目前为止,我一直看到项目以这种方式工作:

1- Controller 从数据库创建模型对象,将其存储在某处(数组、字典、变量)

2- Controller 相应地更新 view,即使使用委托方法 f.i.在 collectionViews 中。

我的问题是:模型是否需要完美地表示视图将要显示的内容?这样我就可以将模型对象传递给视图并根据它设置视图?

到目前为止,我一直在执行此过程,但我想知道这种方法是否有问题。

要明确的例子,在controller:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! PostCollectionviewCell
    cell.currentItem = self.posts[indexPath.item] as? Post 
    return cell
}

view 中使用property observer

   var currentItem :Post?{
    didSet{
            guard let thumbnailUrlString = self.currentItem?.thumbnailUrl else { return }
            self.imageview.sd_setImage(with: URL(string: thumbnailUrlString))
            bottomLayer.isHidden = true
            
        }
    
}

【问题讨论】:

  • IMO “控制器从数据库创建模型对象,将其存储在某个地方”是一个最小的解决方案,它在现实生活中几乎从不工作,因为这意味着您每次控制器都要后端 被重新创建。或者你也在你的视图控制器中转储了一些缓存。最后你有一个怪物。然后你想添加另一个视图控制器(比如显示细节),你需要重复这个工作,或者需要在各个控制器之间来回传递数据。
  • 更好的选择是将“创建要显示的模型”(这是一个视图控制器作业)与“从数据库中检索对象,将其存储在某处”(可能是某种服务)分开,所有控制器都可以访问,获取他们需要的数据,并创建适合他们的模型。这也回答了您的问题:“服务”将拥有原始形式的数据 - 从数据库中检索并缓存。而“控制器”将仅包含与视图当前状态相关的数据,以最易于视图使用的形式。
  • 谢谢@KirilS。 ,“某种服务”是指 Firestore 扩展(根据我使用 Firebase 作为后端)?
  • 我更多地考虑了服务层 (emacsway.github.io/en/service-layer),但可以肯定的是,您可以从简单的数据源开始,如果需要,让它们演变成服务层。要点是您在设计早期将“您检索的数据”与“您显示的数据”分开,并让这两个部分仅在定义明确的协议中进行通信

标签: ios swift model-view-controller model property-observer


【解决方案1】:

你问:

模型是否需要完美地表示视图将要显示的内容?

是的,根据定义,模型是真正将要显示的内容的表示。

这样我可以将模型对象传递给视图并根据它设置视图?

您可以,但不一定要这样做。这是你的电话。这个想法(将模型对象传递给视图)当然是一种方便的模式。对于琐碎的应用,这很好。

问题是您的视图与模型纠缠在一起。相反,您可能希望将您的视图视为更抽象的东西,例如,旨在显示由图像和文本字符串组成的事物列表。然后该视图可用于显示由图像和标题组成的任何事物列表。

至少,您可以定义视图以使用协议(例如,可以在列表中显示的事物的协议),而不是引用具体的模型类型。或者给你的单元格一个简单的configure(image:text:) 方法,让控制器指定要使用的模型属性。

无论如何,我建议不要将模型对象的副本存储在集合视图单元格中。它只会引入混乱:如果您的 UI 允许您编辑对象,您是在单元格中编辑此副本,还是在模型中编辑?从理论上讲,您可以通过观察者传播更改,但这会让人感到困惑,这里没有必要。


我的印象是,您可能将视图控制器视为 MVC“控制器”。相反,许多人认为它更多地是 MVC“视图”的一部分,因为它基本上都是关于准备和填充视图、对用户输入作出反应以及对 UI 事件作出响应。我们中的许多人创建了更抽象的“控制器”(或演示者或视图模型),与 UIKit(或其他任何东西)无关。这还有一个优点是可以让我们为业务逻辑编写单元测试,完全独立于 UI。

这里有一些链接可以重新思考 MVC 的含义和/或考虑一些合乎逻辑的替代方案:

  • 请参阅 Dave Delong 的 A Better MVC,了解采用 MVC 的观点,但采用技术使其小型化和易于管理。

  • 请参阅 Medium 的 iOS Architecture Patterns,了解其他方法,包括 MVP、MVVM、Viper 等。

  • 请参阅 Krzysztof Zabłocki 的 iOS Application Architecture,了解有关该主题的另一个很好的讨论。

【讨论】:

  • 非常感谢!我想更多地理解您所说的“您可以定义视图以使用协议”的部分。他们应该以何种方式使用协议?
  • 您可以使用协议来捕获所需内容的本质。例如,您可能让列表视图使用像 protocol Listable { var imageURL: URL { get }; var title: String { get } } 这样的协议。然后,您的视图现在可以使用具有imageURLtitle 而不仅仅是Post 的任何Listable 类型。一般来说,在编写接口时,总是要问自己它是否真的需要使用特定的具体类型,或者是否有一些抽象可以提供更多的重用机会。
猜你喜欢
  • 2023-03-31
  • 2011-08-17
  • 2011-03-10
  • 2012-03-09
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多