iOS中MVC、MVP、MVVM架构模型

现在我们面对架构设计模式的时候有了很多选择:

  • MVC
  • MVP
  • MVVM
  • VIPER

首先前三种模式都是把所有的实体归类到了下面三种分类中的一种:

  • Models(模型)数据层,或者负责处理数据的 数据接口层。
  • Views(视图)展示层(GUI)。对于 iOS理论上来来说所有以 UI 开头的类基本都属于这层。
  • Controller/Presenter/ViewModel(控制器/展示器/视图模型)
    它是 Model 和 View 之间的胶水或者说是中间人。
    一般来说,当用户对 View 有操作时它负责去修改相应 Model;当 Model 的值发生变化时它负责去更新对应 View。

demo在最下面

一、MVC

  MVC是模型 (model)-视图 (view)-控制器 (controller) 的缩写。它表示的是一种常见的客户端软件开发框架。

(1)首先看看MVC它原来的样子

传统MVC

  经典MVC模式在提出时,大致是上图这样的。在这种架构下,View 是没有状态的,在Model变化的时候它只是简单的被 Controller重绘,尽管这种架构可以在应用里面实现,但是由于 MVC 的三种实体被紧密耦合着,每一种实体都和其他两种有着联系,所以即便是实现了也没有什么意义。

(2)理想化的MVC,也就是苹果的MVC

理想MVC

View 和 Model 之间是相互独立的,它们只通过 Controller 来来负责二者的交互。这样的设计,使得View 和 Model 直接解耦合了。

(3)现实中的MVC

现实MVC

  MVC 鼓励编写大规模的视图控制器,因为 View 的整个生命周期都需要它去管理,Controller 和 View 很难做到相互独立。
  虽然你仍有能力将一些业务逻辑和数据转换成Model,但你没办法将View从Controller中分离。在大多数情况下,View的责任是把事件传递给Controller。
Controller最终演变成一个其他人的delegate和data source,甚至还负责网络请求的发起和取消,另一方面Controller负责了界面跳转的操作,界面跳转的相关配置是直接在对应的Controller实例上设置的,这样就很容易把源界面和目的界面耦合起来,表现在导入很多其他头文件。最后变得臃肿不堪,所以又称之为Massive View Controller(大量的视图控制器)。

在许多情况下,你见到的代码类似于这样:

cell.model = self.dataArray[indexPath.row];

Model和View经常会直接通信,产生了耦合。

二、MVP

MVP架构

  MVC的缺点在于并没有区分业务逻辑和业务展示,这对单元测试很不友好。
  MVP针对以上缺点做了优化,它将业务逻辑和业务展示也做了一层隔离, 对应的就变成了MVCP。
  M和V功能不变,原来的C现在只负责布局,而所有的业务逻辑全都转移到了P层。
  P层处理完了业务逻辑,如果要更改view的显示,那么可以通过回调来实现,这样可以减轻耦合,同时可以单独测试P层的业务逻辑。

  在 MVP 中,P可以理解为松散的控制器,其中包含了视图的 UI 业务逻辑,所有从视图发出的事件,都会通过代理方法Protocol给 P 进行处理;同时,P也通过视图暴露的接口与其进行通信。

  • View负责界面展示和布局管理,向Presenter暴露视图更新和数据获取的接口
  • Presenter负责接收来自View的事件,通过View提供的接口更新视图,并管理Model
  • Model和MVC中的一样,提供数据模型

这个流程看起来确实很像 Apple 的理想化的MVC,它的名字是 MVP(被动变化的 View)。
Apple 的 MVC 实际上是 MVP 吗?不是的

区别就是IOS中:
(1)苹果的理想MVC中UIView相当于View,UIController是Controller,而在MVP中,UIView和UIController都相当于View,所以在 Presenter 里面基本没什么布局相关的代码,它的职责只是通过数据和状态更新 View。
(2)持有关系也不一样,MVC中 C 持有 M和V,但是在MVP中 V 持有 P,P 持有M 。

  MVP相对于MVC,它其实只做了一件事情,即分割业务展示和业务逻辑. 展示和逻辑分开后,只要我们能保证V在收到P的数据更新通知后能正常刷新页面,那么整个业务就没有问题。因为V收到的通知其实都是来自于P层的数据获取/更新操作, 所以我们只要保证P层的这些操作都是正常的就可以了。 即我们只用测试P层的逻辑,不必关心V层的情况。

  所以MVP实现了各模块的解藕,具有更好的可测试性。但是总体代码量比MVC大。

三、MVVM

MVVM架构

  MVVM其实是在MVP的基础上发展起来的。那么MVVM在MVP的基础上改良了啥呢?答案就是数据绑定。
  MVVM各层的职责和MVP的类似,viewModel对应P层,只是在MVVM的View层多了数据绑定的操作。

  • 在MVVM 中,View和Controller正式联系在一起,我们把它们视为一个组件
  • View和Controller 都不能直接引用model,而是引用视图模型(viewModel)
  • viewModel 是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其他代码的地方
  • 使用MVVM会轻微的增加代码量,但总体上减少了代码的复杂性。

MVVM 的使用建议

  • MVVM 配合一个绑定机制效果最好(ReactiveCocoa,KVO)。
  • Controller 尽量不涉及业务逻辑,让 viewModel 去做这些事情。
  • Controller 只是一个中间人,接收 view 的事件、调用 viewModel 的方法、响应 viewModel 的变化。
  • viewModel 绝对不能包含视图 view(UIKit.h),不然就跟 view 产生了耦合,不方便复用和测试。
  • viewModel之间可以有依赖。
  • viewModel避免过于臃肿,否则重蹈Controller的覆辙,变得难以维护。

MVVM优点

  • MVVM 可以兼容你当下使用的MVC架构。
  • MVVM 增加你的应用的可测试性。
  • 低耦合:View 可以独立于Model变化和修改,一个 viewModel 可以绑定到不同的 View 上
  • 可重用性:可以把一些视图逻辑放在一个 viewModel里面,让很多 view 重用这段视图逻辑
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发 viewModel,设计人员可以专注于页面设计
  • 可测试:通常界面是比较难于测试的,而 MVVM 模式可以针对 viewModel来进行测试

缺点

  • 学习成本和开发成本都很高,新人很难上手
  • iOS中,并没有现成的绑定机制可用,要么使用 KVO,要么引入类似 ReactiveCocoa 这样的第三方库
  • 数据绑定使 Debug 变得更难了,堆栈结构更复杂了,使得对象生命周期很难追踪
  • 对于过大的项目,数据绑定需要花费更多的内存
  • ReactiveCocoa 在国内外还都是在小众领域,没有被大量接受成为主流的编程框架。在别的语言中,例如 Java 中的 RxJava 也同样没有成为主流

Demo下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容