常见的客户端架构解析

一千个程序员眼中有一千种 MVC

SmallTalk MVC

MVC.gif

Models

  • Models 表示知识。
  • 一个 Model 可以是单个对象,也可以是一些对象的组合结构。
  • Model 和它的部件之间可能有一对一的通信。
  • 对 Model 的所有者(View)来说,它如实地反映了真实世界。
  • Model 是问题的一个可标示部分。
  • 某个 Model 的所有节点都应该处在同样的问题等级,将面向问题的节点(如日历中的预约)和实现细节(如图形)混在一起是不好的。

Views:

  • View 是它的 Model 的(可见)表示。
  • 它会重点关注 Model 中的某些属性而忽视其它的,因此它也是一个展示过滤器。
  • View 和它的 Model(或者 Model 的一部分)连接。它以问问题的方式得到展示所需的数据,发送合适的消息来更新 Model。所有这些问题和消息都在 Model 的术语中,因此 View 必须知道它所展示的 Model 的属性的语义。

Controllers

  • Controller 是用户和系统的桥梁。
  • 它指定相关的 Views 让它们将自己展示在屏幕的适当位置。
  • 它通过菜单或者其它可以支持命令和数据的形式来表示用户的意图。
  • Controller 不应该去补充 Views,比如它不会在几个 View 之间绘制箭头把它们连接起来。
  • View 永远不会知道用户的输入,譬如鼠标操作和键盘点击。在 Controller 可以写一个方法向 View 发送消息,它可以精确模拟用户的一系列指令。

Editors

  • 一个 Controller 和它所有的 Views 相关联,它们被称为 Controller 的部件。
  • 某些 Views 提供一种特殊的 Controller——Editor。
  • Editor 允许用户修改 View 所展示的信息。
  • 这样的 Editor 可能被插入 Controller 和 View 之间,它表现得像 Controller 的一个扩展。
  • 一旦编辑操作结束,Editor 被移除。
  • Editor 通过它所连接的 View 的 metaphors(隐喻,象征)来和用户交流,因此 Editor 和 View 是强关联的。
  • Controller 只能向 View 请求从而得到一个 Editor 的引用,别无他法。

观点

以上是对 MVC 原始论文的整理翻译。

在 MVC 中,V 可以和 C 通信,V 可以和 M 通信。

最早的 MVC 于 1979 年提出,当时还需要程序员全权处理用户输入——Controller 的职责。而现在,大部分事情已经被操作系统做了,我们已经做不到“View 永远不会知道用户的输入”,我们也不太需要 Editor,因为这些已经被封装进UITextField之类的控件中,View 本身就具备一定的交互功能。用户操作往往被封装成“事件”传递给 View。

所以真正的 MVC 是一种过时的架构。

Apple MVC

Apple MVC.png

Model Objects

  • Model Objects 包括应用所需的数据,并且定义数据处理的逻辑。

  • Model 和 View 之间不该有明确的关联。

  • 用户在 View 层的操作会通过 Controller 增加或改变 Model。

  • Model 一旦改变(譬如从网络获取了新数据),它会通知 Controller,Controller 再去更新 View。

View Objects

  • View Object 是应用中用户可以看到的部分。

  • View 知道如何绘制自己,可以响应用户操作

  • View 展示 Model 中的数据,并且允许编辑这些数据。尽管如此,View 和 Model 是完全解耦的

  • View 通过 Controller 得知 Model 中数据的变化;并且将用户发起的变化通过 Controller 反映到 Model。

Controller Objects

  • Controller 是 View 和 Model 之间的中间人。

  • Controller 也可以用来设置和协调应用的任务、管理其它对象的生命周期。

  • Controller 会将 View 层的变化反映到 Model 层,也会将 Model 层的变化反映到 View 层显示出来。

观点

Apple 所谓的 MVC 跟原始的 MVC 基本已经毫无关系……在这里 C 成了一个中介者,用以协调 V 和 M。

这个模式其实没有特别大的问题,但是由于 Cocoa 中的 ViewController 还承担了 View Container 的工作,我们在日常开发中又容易把 Model 层设计得过于单薄(比如只是一个单纯的数据对象),从而导致 Controller 中有大量本该放在 View 和 Model 中的代码。

所以这是一个最容易被滥用的模式。

MVVM

MVVM.png

ViewModel

  • 一个抽象的视图(AbstractView)。
  • 包含概念:视图状态(ViewState)、数据转换器(ValueConversion)、操作 Model/ViewModel 的指令。

数据绑定

  • 需要一种绑定机制将 View 和 ViewModel 连接起来(View 和 ViewModel 可以用不同语言编写)。

观点

MVVM 由微软架构师 John Gossman 于 1996 年提出,在提出这个概念以前,他们团队早已在实践这个架构了。由于 MVVM 是 MVC 的一种改进,M 和 V 部分和 MVC 是类似的。而 Gossman 认为在现代 GUI 系统中,C 的大部分工作已经由系统帮你做了,所以 C 并没有被抛弃,而是隐藏到幕后了。

MVVM 中的 VM 承担了状态管理、数据转换、操作处理之类的任务,它早先被用于 WPF(View 层由 XMAL 编写,且内建了绑定机制),但写 WPF 并不一定要用 MVVM,你完全可以将 View 和 Model 直接绑定——如果你的程序足够简单。

由于在 iOS 中并没有一个内建的绑定机制,很多人觉得在项目中多一层数据转换层就是 MVVM 了,这有一些片面。我还是觉得真的要用 MVVM 就必须建立一套绑定机制,可以利用 RxSwift 和 RAC 之类的第三方库,或者自己撸一套。

MVP

Passive View variant of MVP.png

1996年,Mike Potel 在一篇论文中提出 Model-View-Presenter 的概念。这个时候的 View 已经跟 MVC 刚诞生时的 View 全然不同了,它可以接受用户输入。MVP 的主要思想是用户输入由 V 流进,V 通过 P 更新 M,同时 V 跟 M 之间还是跟 MVC 中一样,V 可以调用 M 的接口,M 通过观察者模式向 V 广播自身的更新。

同 MVC 一样,而今的 MVP 与最早的 MVP 也相距甚远。现在为人所普遍接受的 MVP 是,V 和 M 完全解耦,通过 P 进行通讯。但和 Apple MVC 不同的是,P 并不包含生命周期控制之类的职责,而且一般是由 V 去持有 P。

观点

MVP 似乎在 Android 开发中比较流行,我没有实践过,不敢妄言。

VIPER

VIPER.png

由 View、Interactor、Presenter、Entity、Router 组成。

观点

同样没有实践过……但直观上感觉是把 MVP 进行了进一步拆分——Presenter 拆为 Presenter 和 Router,Model 拆为 Interactor 和 Entity。

小结

对于结构划分,还是要根据项目规模来,规模大就分层细一点,规模小就粗一点。因为分层越多,层与层之间的通信成本就越高。通信方面可以采取各种手段——接口调用、观察监听、数据绑定等。

我个人比较倾向于分为 View、Model、ViewModel、Router 这几层,以数据绑定为基础进行通信。

各个层最好都定义一个协议来确认各自的职责,可以有一些默认实现。

参考资料:

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

推荐阅读更多精彩内容