为什么要关注架构设计?
因为假如你不关心架构,那么总有一天,需要在同一个庞大的类中调试若干复杂的事情,你会发现在这样的条件下,根本不可能在这个类中快速的找到以及有效的修改任何bug.当然,把这样的一个类想象为一个整体是困难的,因此,有可能一些重要的细节总会在这个过程中会被忽略。如果现在的你正是处于这样一个开发环境中,很有可能具体的情况就像下面这样:
- 这个类是一个UIViewController的子类
- 数据直接在UIViewController中存储
- UIView类几乎不做任何事情
- Model 仅仅是一个数据结构
- 单元测试覆盖不了任何用例
以上这些情况仍旧会出现,即使是你遵循了Apple的指导原则并且实现了其 MVC(模式,所以,大可不必惊慌。Apple所提出的 MVC 模式存在一些问题,我们之后会详述。
在此,我们可以定义一个好的架构应该具备的特点:
- 任务均摊给具有清晰角色的实体
- 可测试性通常都来自于上一条(对于一个合适的架构是非常容易的)
- 易用性和低成本维护
MV(X)系列概要
当今我们已经有很多架构设计模式方面的选择:
- MVC
- MVP
- MVVM
这三种设计模式都把一个应用中的实体分为以下三类:
- Models -- 负责主要的数据或者操作数据的数据访问层,可以想象Person和PersonDataProvider类。
- Views -- 展示层,对于iOS系统可以联想到以UI开头的所有类。
- Controller/Presenter/ViewModel -- 负责协调Model和View,通常根据用户在View上的动作在Model上作出对应的更改,同时将更改的信息返回到View上。
将实体进行划分给我们带来了以下好处:
- 更好的理解它们之间的关系
- 复用(尤其是对于View和Model)
- 独立的测试
MVC
苹果推荐的MVC--愿景![](https://img.haomeiwen.com/i2835383/d0f842c103ae754f.png)
![](https://img.haomeiwen.com/i2835383/75428b0e4155faff.png)
![](https://img.haomeiwen.com/i2835383/070899c2b80e63a2.png)
VC:过重 --> 解重
解重方法:
1、将tableView的dataSource单独抽取出来。
2、将获取数据部分,网络请求独立抽取出来。
MVP
MVP实现了Cocoa的MVC的愿景。如下图:![](https://img.haomeiwen.com/i2835383/e158de4f8c80a0bb.png)
MVP的优缺点:
- 任务均摊 -- 我们将最主要的任务划分到Presenter,而View的功能较少,减轻了View的负担
- 模型与视图完全分离,我们可以修改视图而不影响模型;
- 可以更高效的使用模型,因为所有的交互都发生在一个地方--Presenter内部
- 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的罗辑。这个特性非常有用,因为视图的变化总是比模型的变化频繁;
- 如果我们把罗辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
iOS中的MVP意味着可测试性强、代码量大
MVVM
MVVM架构是MV(X)系列最新的一员,因此让我们希望它已经考虑到MV(X)系列中之前已经出现的问题。
从理论层面来讲MVVM看起来不错,我们已经非常熟悉View和Model,以及Meditor,在MVVM中它是View Model。
![](https://img.haomeiwen.com/i2835383/1aacfc5d1a48e545.png)
它和MVP模式看起来非常像:
- MVVM将ViewController视作View
- 在View和Model之间没有紧密的联系
- ViewModel承担了MVP模式中Presenter的角色,但是它View是双向绑定的
绑定
ViewModel和View之间的双向绑定可以通过KVO或者通知结合block来做,当然如果我们不想自己实现,那我们有两种选择:
- 基于KVO的绑定库如 RZDataBinding 和 SwiftBond
- 完全的函数响应式编程,比如像ReactiveCocoa、RxSwift或者 PromiseKit
事实上,尤其是最近,你听到MVVM就会想到ReactiveCoca,反之亦然。尽管通过简单的绑定来使用MVVM是可实现的,但是ReactiveCocoa却能更好的发挥MVVM的特点。
MVVM的优缺点
- 任务均摊 -- MVVM的View要比MVP中的View承担的责任多。因为前者通过ViewModel的设置绑定来更新状态,而后者只监听Presenter的事件但并不会对自己有什么更新。
- 可测试性 -- ViewModel不知道关于View的任何事情,这允许我们可以轻易的测试ViewModel。同时View也可以被测试,但是由于属于UIKit的范畴,对他们的测试通常都会被忽略。
- 易用性 -- MVP在实际开发中,我们必须把View中的事件指向Presenter并且手动的来更新View,如果使用绑定的话,MVVM的代码量将会小的多。
MVVM很诱人,因为它集合了上述方法的优点,并且由于在View层的绑定,它并不需要其他附加的代码来更新View,尽管这样,可测试依然很强。
为了更好的理解和学习MVP和MVVM架构模式,我编写了示例代码,仅供大家学习和参考。
网友评论