IOS MVC、MVP、MVVM、VIPER架构详解
2020-01-02 本文已影响0人
有梦想的狼
何为架构?
- 软件开发中的设计方案。
- 类与类之间的关系、模块与模块之间额关系、客户端与服务端的关系。
经常听到的架构名词?
- MVC、MVP、MVVM、VIPER、CDD。
- 三层架构、四层架构。
MVC
Model-View-Controller
- Model:
模型对象封装了应用程序的数据,并定义操控和处理该数据的逻辑和运算。例如,模型对象可能是表示商品数据 list。用户在视图层中所进行的创建或修改数据的操作,通过控制器对象传达出去,最终会创建或更新模型对象。模型对象更改时(例如通过网络连接接收到新数据),它通知控制器对象,控制器对象更新相应的视图对象。 - View:
视图对象是应用程序中用户可以看见的对象。视图对象知道如何将自己绘制出来,可能对用户的操作作出响应。视图对象的主要目的就是显示来自应用程序模型对象的数据,并使该数据可被编辑。尽管如此,在 MVC 应用程序中,视图对象通常与模型对象分离。
在iOS应用程序开发中,所有的控件、窗口等都继承自 UIView,对应 MVC 中的 V。UIView 及其子类主要负责 UI 的实现,而 UIView 所产生的事件都可以采用委托的方式,交给 UIViewController 实现。 - Controller:
在应用程序的一个或多个视图对象和一个或多个模型对象之间,控制器对象充当媒介。控制器对象因此是同步管道程序,通过它,视图对象了解模型对象的更改,反之亦然。控制器对象还可以为应用程序执行设置和协调任务,并管理其他对象的生命周期。
控制器对象解释在视图对象中进行的用户操作,并将新的或更改过的数据传达给模型对象。模型对象更改时,一个控制器对象会将新的模型数据传达给视图对象,以便视图对象可以显示它。
- 优点:View、Model可以重复利用。
- 缺点:Controller的代码过于臃肿。
MVP
Model View Presenter(模型 视图 协调器)
- Model:
数据对象,包含网络请求,以及数据 SQLite 的 CRUD(增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)) 操作(比如 iOS 平台,一般以 FMDB 框架直接操作 sql,或者用 CoreData) 。一般可以将数据对象是否需要缓存设计成一个字段 isCache,或者针对整个项目设计一个开存储关,决定整个项目是否需要数据缓存。我们常见的新闻类 App,在离线的时候看到的数据,都是做了缓存处理的。比如一些金融类的 App,实时性比较高,是不做缓存的。 - View:
就是 View 的一些封装、重用。在一款精心设计过的 App 里面,应该有很多 View 是可以封装重用的。比如一些自己的 TableViewCell,自己设计的 Button,一些 View(包含一些子 View,UI 精心设计过,在项目里多处出现的)等等。 -
Presenter:
只是 Model 层和 View/ViewController层的一个桥梁。Presenter 层就不至于太臃肿,容易看懂。一些大的 App,或因为上线时间比较久了,经历过众多程序员的修补,或因前期并未做好架构,以至于打开一个类,几千行的代码,看着自己都晕。
MVP - 优点:
模型与视图完全分离,我们可以修改视图而不影响模型
可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
我们可以将一个Presener用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试) - 缺点:
由于对视图的渲染放在了Presenter中,所以视图和Persenter的交互会过于频繁。
还有一点你需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么 Presenter也需要变更了。比如说,原本用来呈现Html的Presenter现在也需要用于呈现Pdf了,那么视图很有可能也需要变更。
MVVM
View、View Model、Model这三部分之间的相互解耦。
- Model:
与业务和验证逻辑有关的域模型,都可以认为是MVVM中的Model。比如:业务对象,数据传输对象(DTOs),实体,代理对象等等都可以认为是Model。
这里的Model与MVC中的Model一样。 - View:
View负责定义页面结构,布局用户在屏幕上看到的界面。在iOS开发中,View一般是程序中的一个页面。一个View也可以是父View的一部分。
每个View都有自己的View Model,或者它从父View中继承了View Model。View通常是通过通过View Model的绑定,或者调用View Model中的方法来获取数据。在运行的时候,UI控件要响应View Model抛出通知事件,来更新UI。
为了响应UI上的交互,需要在View Model中实现相应的代码。比如一个按钮被点击。需要将这个按钮点击事件绑定到View Model中去。然后在View Model中写代码处理用户的交互。
在iOS开发中View和ViewController都是属于View这部分。 - View Model:
View Model扮演着View和Model的中介角色,它负责处理视图逻辑和数据转化。一般来说View Model通过调用Model的方法来和Model进行交互。View Model随后将从Model中获取的数据以一种view容易使用的格式提供给View。View Model负责UI交互的响应代码实现。例如:当用户点击了一个按钮在UI中,这个动作会使得View Model中相应代码被执行。View Model也负责控制视图的显示逻辑,比如修改UI指示操作正在进行。
- 优点:
方便测试 便于代码的移植。
兼容MVC。 - 缺点:
类会增多,ViewModel会越来越庞大,调用复杂度增加。
VIPER
- View(视图)
提供完整的视图,负责视图的组合、布局、更新
向Presenter提供更新视图的接口
将View相关的事件发送给Presenter - Presenter(展示器)
接收并处理来自View的事件
向Interactor请求调用业务逻辑
向Interactor提供View中的数据
接收并处理来自Interactor的数据回调事件
通知View进行更新操作
通过Router跳转到其他View - Router(路由)
提供View之间的跳转功能,减少了模块间的耦合
初始化VIPER的各个模块 - Interactor(交互器)
维护主要的业务逻辑功能,向Presenter提供现有的业务用例
维护、获取、更新Entity
当有业务相关的事件发生时,处理事件,并通知Presenter - Entity(实体)
和Model一样的数据模型
- 优点:
可测试性好。UI测试和业务逻辑测试可以各自单独进行。
易于迭代。各部分遵循单一职责,可以很明确地知道新的代码应该放在哪里。
隔离程度高,耦合程度低。一个模块的代码不容易影响到另一个模块。
易于团队合作。各部分分工明确,团队合作时易于统一代码风格,可以快速接手别人的代码。 - 缺点:
一个模块内的类数量增大,代码量增大,在层与层之间需要花更多时间设计接口。
模块的初始化较为复杂,打开一个新的界面需要生成View、Presenter、Interactor,并且设置互相之间的依赖关系。而iOS中缺少这种设置复杂初始化的原生方式。