Swift中MVC的替代方法:基本MVVM结构
MVVM(模型-视图-视图-模型)和MVC(模型-视图-控制器)是iOS设计模式。 Apple将设计模式定义为设计的模板,以解决特定情况下的普遍性重复性问题。 它是一种抽象工具,在诸如体系结构和工程以及软件开发等领域非常有用。
在MVVM中,我们在不同的MVC层之间添加了一个称为ViewModel的层。 它由引用我们要表示或交流的实例的类或结构组成。
假设我们要列出服务的结果。 在此示例中,我将列出新闻来源。 为了做到这一点,我创建了Source模型类:
类来源{
var id:String
变量名:String
var说明:String
init(id:String,name:String,description:String){self.id = id
self.name =名称
self.description =说明
} // ...
如果我们想在ViewController中列出我们的Sources,我们可以使用一个封装Controller所需信息的类。 我们称它为SourceViewModel:
类SourceViewModel {var id:String
变量名:String
var说明:String
init(source:Source){self.id = source.id
self.name =源名称
self.description = source.description
} // ...
但是,控制器需要的信息不是来源的信息,而是来源列表的信息。 因此,我们需要诸如更高级别的视图模型,源(列表)视图模型之类的东西。 创建它:
类SourceListViewModel {
private var webservice:Web服务
私有(一组)var sourcesViewModel:[SourceViewModel] = [SourceViewModel]()
私人var完成:()->()= {}
init(webservice:Webservice,完成:@escaping()->()){self.webservice = webservice
self.completion =完成
populateSources()
}
私人功能populateSources(){self.webservice.loadSources {来源inself.sourcesViewModel = sources.compactMap(SourceViewModel.init)
self.completion()
}
} // ...
这是我们的ViewController将会接收的对象,并且具有填充列表所需的所有信息。 这里发生了什么?
- SourceListViewModel类使用WebService,在这种情况下,该WebService代表向我们提供Source的服务。 这是私有的,但是是由构造函数注入的,这使我们的ViewModel可测试。
- 此类还具有SourceViewModel的集合,我们的ViewController将使用该集合来填充视图。 这个收藏品有一个私人的设定者 ,但有一个公共的吸收者 。
- 此类也有一个专用块,但将在成功初始化后执行。
- populateSources()辅助方法,无非就是使用WebService服务来获取Source模型的实例。 因此,我们可以实例化SourceViewModel。
我们在ViewController中使用更高级别的ViewModels。 为了列出我们的Source,我们通过以下方式使用ViewController:
类SourcesTableViewController:UITableViewController {
private var webservice:Web服务!
私有var sourceListViewModel:SourceListViewModel!
覆盖func viewDidLoad(){super.viewDidLoad()
self.webservice = Webservice()
self.sourceListViewModel = SourceListViewModel(webservice:self.webservice,完成:{
self.tableView.reloadData()
})
} // ...
在ViewController中初始化SourceListViewModel之后,我们将使用它来填充它,在这种情况下,我们将使用集合的数据加载表。 如下使用集合:
//标记:-表格视图数据源覆盖功能func numberOfSections(在tableView中:UITableView)-> Int {
返回1
}覆盖func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {
返回sourceListViewModel.sourcesViewModel.count
}
覆盖func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:“ Cell”,for:indexPath)
让sourceViewModel = self.sourceListViewModel.sourcesViewModel [indexPath.row]
cell.textLabel?.text =“ \(String(描述:sourceViewModel.firstName!))\(String(描述:sourceViewModel.lastName!))”“
返回单元
} // ...
这是实现此模式的基本示例。 我们可以使用泛型来创建泛型数据源,并将其注入到我们的View Controllers和Promises中,以避免服务和View模型中的块。 这就是我们可以实现更清洁,可读和可测试的体系结构的方式。