iOS架构模式(MVC/MVCS/MVP/MVVM/VIPER)

1,593 阅读9分钟

一个iOS开发者在成长到一定阶段后,就会遇到瓶颈,解决的方法就是熟悉设计模式,接触App架构。App架构类似于现代建筑的脚手架或者是地基,一旦确定,剩下的工作就是在现成的App里添砖加瓦。

什么是好的架构: 高内聚,低耦合。 代码均摊,易于测试,具有易用性。

MVC

MVC,即 Model-View-Controller。它是苹果公司官方推荐的 App 开发架构,也是一般开发者最先遇到、最经典的架构。 图下所示的是苹果 MVC架构的示意图。

image.png

1. 分工总结

它把整个 APP 分成了三个部分:

Model:数据层,负责存储数据和处理业务逻辑;

View:视图层, 负责数据的展示和交互;

Controller: 控制器层,中介者,协调model 和 view 控制器层。它将数据从 Model 层传送到 Vie层并展示出来,同时将 View 层的交互传到 Model 层以改变数据.

相比传统的 MVC,苹果的 MVC 的特点是,Model 层和 View 层是相互独立的。

2. 通讯规则

如下:

  1. controller能够访问Model和View, Model 和View 不能互相访问

  2. view 与用户交互产生事件时,使用target-action 方式来处理

  3. 当view需要处理一些特殊UI逻辑或获取数据源时,通过delegate 或 data source 方式交给controller来处理,进而通过controller改变Model层以改变数据.

  4. Model 不能直接与Controller 通信,当Model 有数据更新时,可以通过Notification 或 KVO 来通知Controller更新View

image.png

由于 Controller 承担的任务相对较重,在实际开发中,很多初级开发者直接将 View 和 Controller 部分的代码全部塞到了 ViewController 类中,造成了它们的高度耦合。如何解耦View 和 Controller,在 iOS 开发中是一个热门的话题。

3.优点

MVC 架构的优点有以下两个。

  1. 代码总量少。基本上,MVC大量的逻辑和视图代码都集中在 ViewController中,View和 Model 也严格区分,代码分配遵循一定的规则。
  2. 简单易懂。对于 MVC,新人可以快速上手,修改和增加新的功能也没有明显障码,即使是没有经验的开发者也能很好地维护。

4.优点

MVC 架构的缺点主要是由视图层和控制器层高度耦合造成的,负面影响主要为:

  1. 代码过于集中。ViewController 因为将两部分高度耦合,它将处理交互、视图更新 布局、Model 数据获取和修改、导航等几乎所有操作。
  2. 难以进行测试。由于高度耦合,使得以检测功能为主的单元测试需要配合特定视图才能进行,让测试难度陡增。所以,在 MVC 中,开发者一般只对 Model 进行测试。
  3. 难以扩展。在 ViewController 中添加新功能需要格外小心,高度耦合的逻辑结构增加了出错的风险,同时,由于 View 和 Controller 部分互相依赖,增加新功能不仅可能需要大量修改原有代码,也会使 ViewController 愈发笨重。
  4. Model 层过于简单。相比 ViewController 的庞大代码,Model 层只是定义几个属性在 Objective-C 的.m 实现文件中,更是几乎看不到代码。
  5. 网络请求逻辑无从安放。网络层放在 Model 中,其异步调用的 API请求会使得整个Model层变得复杂,若是将网络层放在ViewController中,则耦合进一步加剧,以上缺点更会被放大。

MVP

示意图如下 image.png

1. 分工总结

分工总结:

  1. 视图(View):用户界面
  2. 模型(Model):数据存储
  3. 展示器(Presenter):数据处理,业务逻辑。

2. 通讯规则

通讯规则如下:

  1. view 持有并且发送交互给Presenter。
  2. Presenter持有并且更新Model,Presenter弱持有view,更新view。 Presenter持有并且更新Model是View和Model的桥梁,它会根据View的交互修改Model,或根据Model的变化修改View。

View和Presenter之间是完全解耦的,他们通过接口来交互 View和Presenter是一对一关系,意味着一个Presenter只映射一个View,且他们之间是可以双向交互的。

3. 优点

MVP优点

  1. 相比于MVC,耦合度大大降低,模型与视图完全分离,代码分配更加合理,我们可以修改视图而不影响模型。
  2. 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试),调试起来更加方便,整体架构理解和上手难度也不大。
  3. 我们将一个Presenter用于多个视图,而不需要改变Presenter的逻辑,这个特性非常有用,因为视图的变化总是比模型的变化频繁. 或者将Presenter进行继续拆分。

4. 缺点

MVP缺点

view的所有交互都要传给Presenter处理,从而一旦功能增加了,View的代码和Presenter的代码都会增加,相比于MVC在ViewController一个文件里面直接解决,MVP的总代码量可能会翻倍,这样App的维护成本和文件都会增大。

精髓点: 目标需求驱动代码

  1. 写什么样的接口

  2. 谁成为代理

  3. 谁实现代理

MVVM

在MVC的基础上分离出业务处理的逻辑到ViewModel层,即

image.png

1. 分工总结

分工总结: Model: Model层,请求的原始数据、数据持久化

V: View层,由ViewController来控制

VM:ViewModel层,负责网络请求、业务处理和数据转换。

ViewModel 一般扮演两个重要角色:

  1. 视图层的真正数据提供者。一般视图层展示的数据经常是一个或是多个模型的展性 合。例如,微博数据流界面,可能一个微博用户模型有 firstName、lastName、status、的更 post 等多个属性,ViewModel 就会将这些数据整合在一起,使得视图直接调用单个载据就能展示所要的效果。简单来说,ViewModel 就是为了视图展示而对模型层的数据进行包装。
  2. 视图层的交互响应者。所有用户的交互都会传递给 ViewModel。ViewModel会依次更新视图层需要的属性,同时相应修改模型层的数据。这里依靠的是属性观察或响应架构

2. 通讯规则

通讯规则如下:

  1. view持有ViewModel。
  2. 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

image.png

1. 分工总结

分工总结: VIPER 分别由5部分组成:

  1. View,视图层,与 MVP 或者 MVVM 的视图层类似。它包含与UI相关的一切操作。它接收用户的交互信息但并不处理,而是传递给展示层(Presenter)。
  2. Interactor,数据管理层,专门负责处理数据源信息,包括网络请求、数据传输、缓存、存储、生成实例等操作。实际上,之前中间层和模型层的一些逻辑被进一步剥离至此,整个架构的逻辑也显得更加清晰。
  3. Presenter,展示层,与 MVP 的 Presenter 或是 MVVM 的 ViewModel 功能类似。对于其更像 MVP 的 Presenter,还是更像 MVVM 的 VicwModel,取决于其中是否引入响应式编程框架。Presenter 在这里只响应并处理视图层传来的交互操作请求,并不直接对数据源进行修改,这是与 MVX 中间层最大的不同。/若要修改数据,展示层会向其持有的数据管理层(Interactor)发送请求,Interactor 会处理一切有关数据源的操作。此外,它还连接了路由层(Router)。
  4. Entity, 模型层,只拥有初始化方法和属性相关 set/get 方法,与之前的 Model 层大同小异。
  5. Router,路由层,专门负责界面跳转和组件之间的切换。当 App 占用空间较小时, Router 负责页面跳转。当 App 占用空间比较大时,不同的功能和业务会被拆分成不同的模块或组件,Router 的作用就是在不同组件之间进行连接。这是 MVX 架构所忽略的部分。

2. 通讯规则

通讯规则:

  1. view 持有并且发送交互给Presenter.
  2. Prsenter持有并且要求Interactor更新模型。
  3. Interactor知道Entity模型。

3. 优点

优点:

由于分工明确,VIPER 层在代码分配、测试覆盖率上为所有架构之冠。

4. 缺点

缺点:

而 VIPER 的缺点在于,

  1. 它依然与 MVX 架构一样,是一个视图驱动的架构。
  2. VIPER由于分工精细,不同层级之间交互的代码很多,总体代码量很大,不适宜用在小型 App中