前言
本篇文章介绍一下在 iOS 开发中常用的架构模式。
好的架构应该具有哪些特征呢?
1、每个对象都拥有一个特定、明确的角色
2、有一个简单的数据流,容易理解,方便调试
3、不依赖于某个特定的框架或者服务
4、足够灵活,架构容易理解,修改容易
5、可测试性
MVC, MVVM, MVP,三种模式都是把所有的实体归类到了下面三种分类中的一种:
- Models(模型) 数据层,或者负责处理数据的 数据接口层
- Views(视图)展示层(GUI)。对于 iOS 来说所有以 UI 开头的类基本都属于这层
- Controller/Presenter/ViewModel(控制器/展示器/视图模型)它是 Model 和 View 之间的中间人。一般来说,当用户对 View 有操作时它负责去修改相应 Model,当 Model 的值发生变化时它负责去更新对应 View
MVC
MVC是构建 iOS App 的标准模式,是 Apple 推荐的一个架构模式,Apple 认为我们应该做的是,Controller 用于协调 View 和 Model 之间的关系,然后 Controller 是功能最多的部分,所以人们总是会将 View Controller 称之为Massive View Controller(重量级视图控制器)。
via: Stanford CS193p在实际的项目中,我们常常把 Model 放到了 Controller 里,而且 Model 也无法与 Controller 进行有效的通讯 (图中的 Notification & KVO 部分),另外 View Controller 与 View 的生命周期绑定得非常紧密,这导致 Controller 承载了太多的功能,没办法将这三者清晰地分离开来。MVC 的三种实体被紧密耦合着,每一种实体都和其他两种有着联系。View Controller 和 View 的权责被交织在了一起。人们在 View Controller 当中实现网络请求、下载、数据处理,会使得 Controller 非常臃肿,导致测试变得异常困难。传统的 MVC 已经不适合当下的 iOS 开发了。
MVVM
MVC 架构模式的几个不能避免的问题严重困扰开发者,厚重的ViewController、职责划分不清晰、较差的可测试性等,因此也就会有维护性较强、耦合性很低的一种新架构MVVM (MVC 引申出得新的架构)的流行。
View 持有 ViewModel 的引用,反之没有。ViewModel 持有 Model 的引用,反之没有
比起 MVC,MVVM 多了一个 ViewModel 用来处理一些业务逻辑、验证逻辑、网络请求等,要注意的是,任何视图本身的引用都不应该放在 ViewModel 中,ViewModel 是独立于 UIKit 的 。MVVM 架构把 ViewController 看做 View。View 和 Model 之间没有紧耦合。
- MVC中在 C 中获取到数据 M ,然后将 M 传递给 V,V上面有点击事件的时候传给 C,C 处理后改变 M,在传给 V 刷新页面。
- MVVM中在 VM 中获取数据 M ,M 更新的时候,通过 VM 和 V 之间的绑定,然后刷新 V。V 中有点击事件交给 VM 去处理,VM 处理后刷新 V。
将逻辑代码、网络请求等都写入了VM中,然后又由于VM中包含了所有的展示逻辑而且不会引用V,所以它是可以通过编程充分测试的。
ViewModel 能主动调用对 Model 做更改,也能在 Model 更新的时候对自身进行调整,然后通过 View 和 ViewModel 之间的绑定,对 View 也进行对应的更新。它的职责就是作为一个表现视图显示自身所需数据的静态模型;它也有收集, 解释和转换那些数据的责任,这留给了 view (controller) 一个更加清晰明确的任务: 呈现由 ViewModel 提供的数据。
View 和 ViewModel 之间的绑定,在 iOS 中我们可以使用 KVO 和 通知,但是用这些方式去做绑定不太方便。使用全量级的函数式响应编程框架,比如 ReactiveCocoa、RxSwift。
实际上,提到 MVVM 就应该会想到 ReactiveCocoa。虽然我们可以通过简单的绑定来实现 MVVM 模式,但是 ReactiveCocoa(或者同类型的框架)会让你更大限度的去理解 MVVM。
MVP
在 MVP 架构模式中,把大部分的职责都分配到了 Presenter 和 Model 里面,而 View 基本上不需要做什么。
在 MVC 里面 View 和 Controller 是耦合紧密的,但是对于 MVP 里面的 Presenter 来讲,它完全不关注 ViewController 的生命周期,而且 View 也能被简单 mock 出来,所以在 Presenter 里面基本没什么布局相关的代码,它的职责只是通过数据和状态更新 View。
简单写了个小例子,希望可以帮助理解,如有错误还望指正。
GitHub: MV-X_Project
Reference
http://yulingtianxia.com/blog/2015/05/21/ReactiveCocoa-and-MVVM-an-Introduction/
https://blog.coding.net/blog/ios-architecture-patterns
网友评论