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
}覆盖f​​unc 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模型中的块。 这就是我们可以实现更清洁,可读和可测试的体系结构的方式。


您是正在寻找具有挑战性的新项目的开发人员还是设计师? 您在寻找开发人员还是设计师? 美国职棒大联盟最适合您!