一个iOS开发者在成长到一定阶段后,就会遇到瓶颈,解决的方法就是熟悉设计模式,接触App架构。App架构类似于现代建筑的脚手架或者是地基,一旦确定,剩下的工作就是在现成的App里添砖加瓦。
什么是好的架构:
高内聚,低耦合。 代码均摊,易于测试,具有易用性。
MVC
MVC,即 Model-View-Controller。它是苹果公司官方推荐的 App 开发架构,也是一般开发者最先遇到、最经典的架构。 图下所示的是苹果 MVC架构的示意图。
1. 分工总结
它把整个 APP 分成了三个部分:
Model:数据层,负责存储数据和处理业务逻辑;
View:视图层, 负责数据的展示和交互;
Controller: 控制器层,中介者,协调model 和 view 控制器层。它将数据从 Model 层传送到 Vie层并展示出来,同时将 View 层的交互传到 Model 层以改变数据.
相比传统的 MVC,苹果的 MVC 的特点是,Model 层和 View 层是相互独立的。
2. 通讯规则
如下:
-
controller能够访问Model和View, Model 和View 不能互相访问
-
view 与用户交互产生事件时,使用target-action 方式来处理
-
当view需要处理一些特殊UI逻辑或获取数据源时,通过delegate 或 data source 方式交给controller来处理,进而通过controller改变Model层以改变数据.
-
Model 不能直接与Controller 通信,当Model 有数据更新时,可以通过Notification 或 KVO 来通知Controller更新View
由于 Controller 承担的任务相对较重,在实际开发中,很多初级开发者直接将 View 和 Controller 部分的代码全部塞到了 ViewController 类中,造成了它们的高度耦合。如何解耦View 和 Controller,在 iOS 开发中是一个热门的话题。
3.优点
MVC 架构的优点
有以下两个。
- 代码总量少。基本上,MVC大量的逻辑和视图代码都集中在 ViewController中,View和 Model 也严格区分,代码分配遵循一定的规则。
- 简单易懂。对于 MVC,新人可以快速上手,修改和增加新的功能也没有明显障码,即使是没有经验的开发者也能很好地维护。
4.优点
MVC 架构的缺点
主要是由视图层和控制器层高度耦合造成的,负面影响主要为:
代码过于集中。
ViewController 因为将两部分高度耦合,它将处理交互、视图更新 布局、Model 数据获取和修改、导航等几乎所有操作。难以进行测试。
由于高度耦合,使得以检测功能为主的单元测试需要配合特定视图才能进行,让测试难度陡增。所以,在 MVC 中,开发者一般只对 Model 进行测试。难以扩展。
在 ViewController 中添加新功能需要格外小心,高度耦合的逻辑结构增加了出错的风险,同时,由于 View 和 Controller 部分互相依赖,增加新功能不仅可能需要大量修改原有代码,也会使 ViewController 愈发笨重。Model 层过于简单。
相比 ViewController 的庞大代码,Model 层只是定义几个属性在 Objective-C 的.m 实现文件中,更是几乎看不到代码。网络请求逻辑无从安放。
网络层放在 Model 中,其异步调用的 API请求会使得整个Model层变得复杂,若是将网络层放在ViewController中,则耦合进一步加剧,以上缺点更会被放大。
MVP
示意图如下
1. 分工总结
分工总结
:
- 视图(View):用户界面
- 模型(Model):数据存储
- 展示器(Presenter):数据处理,业务逻辑。
2. 通讯规则
通讯规则
如下:
- view 持有并且发送交互给Presenter。
- Presenter持有并且更新Model,Presenter弱持有view,更新view。 Presenter持有并且更新Model是View和Model的桥梁,它会根据View的交互修改Model,或根据Model的变化修改View。
View和Presenter之间是完全解耦的,他们通过接口来交互 View和Presenter是一对一关系,意味着一个Presenter只映射一个View,且他们之间是可以双向交互的。
3. 优点
MVP优点
- 相比于MVC,耦合度大大降低,模型与视图完全分离,代码分配更加合理,我们可以修改视图而不影响模型。
- 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试),调试起来更加方便,整体架构理解和上手难度也不大。
- 我们将一个Presenter用于多个视图,而不需要改变Presenter的逻辑,这个特性非常有用,因为视图的变化总是比模型的变化频繁. 或者将Presenter进行继续拆分。
4. 缺点
MVP缺点
view的所有交互都要传给Presenter处理,从而一旦功能增加了,View的代码和Presenter的代码都会增加,
相比于MVC在ViewController一个文件里面直接解决,MVP的总代码量可能会翻倍,这样App的维护成本和文件都会增大。
精髓点: 目标需求驱动代码
-
写什么样的接口
-
谁成为代理
-
谁实现代理
MVVM
在MVC的基础上分离出业务处理的逻辑到ViewModel层,即
1. 分工总结
分工总结
:
Model: Model层,请求的原始数据、数据持久化
V: View层,由ViewController来控制
VM:ViewModel层,负责网络请求、业务处理和数据转换。
ViewModel 一般扮演两个重要角色:
视图层的真正数据提供者
。一般视图层展示的数据经常是一个或是多个模型的展性 合。例如,微博数据流界面,可能一个微博用户模型有 firstName、lastName、status、的更 post 等多个属性,ViewModel 就会将这些数据整合在一起,使得视图直接调用单个载据就能展示所要的效果。简单来说,ViewModel 就是为了视图展示而对模型层的数据进行包装。
视图层的交互响应者
。所有用户的交互都会传递给 ViewModel。ViewModel会依次更新视图层需要的属性,同时相应修改模型层的数据。这里依靠的是属性观察或响应架构
。
2. 通讯规则
通讯规则
如下:
- view持有ViewModel。
- ViewModel持有并且更新Model。 ViewModel和View建立双向绑定关系,当一个发生改变,另一个跟着改变。
3. 优点
优点
:
相比于MVP,双倍的代码量,MVVM 借助于响应式代码量减少。
4. 缺点
缺点
:
需要引入第三方响应式框架,因为属性观察环环相扣,调用栈很大,所以Debug起来尤其痛苦。
1. MVVM view 和 viewmodel 和 model 的关系
view 持有 viewModel,viewModel为view提供数据。 viewModel 持有 mode, model存储原始数据,viewmodel,存储view可以直接使用的数据, 并且view和viewModel实现双向绑定。
简单来说,就是API请求完数据,解析成Model,之后在ViewModel中转换成能够直接被视图层使用的数据,交付给前端。
经过ViewModel转换之后的数据由ViewModel保存,与数据相关的处理都将在ViewModel中处理,ViewModel返回给View层。
View层由ViewController控制的,View层只做展示,不做业务,view层数据由ViewModel提供。
在MVVM中,我们趋向于将View 和ViewController作为一个整体,新的ViewModel代替原来的ViewController协调View与Model之间的交互。
使用ReactiveCocoa来处理, ReactiveCocoa将会监控数据模型model的变化,并将这个变化映射到视图模型(viewModel)的属性上,执行任意必要的业务逻辑。
2. 不用 RAC 怎么实现 MVVM
- 利用 KVO 实现双向绑定
VIPER
1. 分工总结
分工总结
:
VIPER 分别由5部分组成:
View
,视图层,与 MVP 或者 MVVM 的视图层类似。它包含与UI相关的一切操作。它接收用户的交互信息但并不处理,而是传递给展示层(Presenter)。Interactor
,数据管理层,专门负责处理数据源信息,包括网络请求、数据传输、缓存、存储、生成实例等操作。实际上,之前中间层和模型层的一些逻辑被进一步剥离至此,整个架构的逻辑也显得更加清晰。Presenter
,展示层,与 MVP 的 Presenter 或是 MVVM 的 ViewModel 功能类似。对于其更像 MVP 的 Presenter,还是更像 MVVM 的 VicwModel,取决于其中是否引入响应式编程框架。Presenter 在这里只响应并处理视图层传来的交互操作请求,并不直接对数据源进行修改,这是与 MVX 中间层最大的不同。/若要修改数据,展示层会向其持有的数据管理层(Interactor)发送请求,Interactor 会处理一切有关数据源的操作。此外,它还连接了路由层(Router)。Entity
, 模型层,只拥有初始化方法和属性相关 set/get 方法,与之前的 Model 层大同小异。Router
,路由层,专门负责界面跳转和组件之间的切换。当 App 占用空间较小时, Router 负责页面跳转。当 App 占用空间比较大时,不同的功能和业务会被拆分成不同的模块或组件,Router 的作用就是在不同组件之间进行连接。这是 MVX 架构所忽略的部分。
2. 通讯规则
通讯规则
:
- view 持有并且发送交互给Presenter.
- Prsenter持有并且要求Interactor更新模型。
- Interactor知道Entity模型。
3. 优点
优点
:
由于分工明确,VIPER 层在代码分配、测试覆盖率上为所有架构之冠。
4. 缺点
缺点
:
而 VIPER 的缺点在于,
它依然与 MVX 架构一样,是一个视图驱动的架构。
VIPER由于分工精细,不同层级之间交互的代码很多,总体代码量很大,不适宜用在小型 App中
。