MVVM 不是那么好

作者:Soroush Khanlou,原文链接,原文日期:2015-12-17
译者:zltunes;校对:Channe;定稿:shanks

我写过许多关于让 ViewController 变得更轻量的文章,Model-View-ViewModel 是一种常用的可以实现该目的的设计模式。我觉得 MVVM 是一种反人类的设计模式,它使架构更加混乱而非清晰。View Model的命名很糟糕,它只是架构优化的权宜之计。对我们来说放弃这一模式反而更好。

MVVM 命名很糟糕

名称是很重要的。一个理想的名称能够有效地传达出对象是干什么的,扮演什么角色以及怎么使用它。View Model这一名称则没有发挥任何作用。

在我看来,View Model这个十分抽象的名称实际上指的是两个截然不同的设计模式。

View Model的第一种含义是 model for the view(视图的模型)。这是一个愚蠢的对象(严格来讲 Swift 中叫struct),用来传递给某个视图去填充它的子视图。它不应该包含任何逻辑或方法。类似于UILabel需要一个字符串,UIImageView 需要一张图像,ProfileView需要一个ProfileViewModel。该对象直接传递给ProfileView,它允许你的子视图是私有的而非暴露给外界,这是很有用的一点。我更喜欢把这种设计模式叫做view data,因为它把自己从view model的另一种定义的包袱中除去了。

View model另一种含义是介于模型和视图控制器之间的一种模糊、抽象的对象。负责将数据传递给表示层,有时候也作为网络和数据库通道,或者表单验证以及其他类似的任务。这种“万金油”式的对象可以为你的控制器减压,但往往最后会成为一个新的“下水道”,什么任务都往里面堆。

MVVM 引进太多职责

命名不够具体,导致这个类的任务无休止地增长。到底哪些任务应该交给view model?没有人知道,好像什么都能交给它。

让我们看一些例子。

  • 这里将网络请求放入view model,并建议你添加验证和表示的逻辑。
  • 这里只展示了如何将表示逻辑放到view model中,并提出为什么不把它命名为Presenter的问题。
  • 这里讲到用view model上传数据并绑定到ReactiveCocoa
  • 这里view model进行验证和获取数据。
  • 这里明确建议你在view model中放入“其他代码”:

view model 非常适合干这些事:验证逻辑、用户输入、视图展示逻辑、网络请求以及其他代码。

没有人知道view model到底是什么意思,所以无法就“哪些功能交给 view model”达成一致。它本身概念过于抽象。这些作者对一个 Validator 类、Presenter 类或者 Fetcher 类该做什么是没有异议的,这些名字都起得很好,能准确传达出对应类扮演的角色。

给用途截然不同的对象起同一个名字只能给读者造成困惑。如果我们不能就view model的功能达成一致,为什么要给他们起这个名字?

这种看法面临着一个类似的挑战,我们发现controller这个名称同样太宽泛,无法包含一系列确切的任务。

你自己的类叫什么名字完全由你决定,选个好听的就是了!

MVVM 不改变你的架构

view model 并不能从根本上改变你的应用程序的架构。这两张图有什么不同(原图)?

不需要利用先进的图片理论你也能看出这两张图几乎是一样的。

我能想到的 MVVM 模式最大的好处就是它把“下水道”从苹果自带的 view controoller类转移到了view model这一自定义的对象。view controller只需要专注于视图生命周期事件即可,变得很简洁。尽管如此,还是有“下水道”存在,仅仅是转移了而已。

由于view model只是给 app 添加的一层定义简陋的模块,仍无法解决复杂性的问题。如果你为了避免view controller过于臃肿而创建了view model,那么当你的代码规模加倍的时候会发生什么?也许我们可以加一个controller-model层。

view model方案不能大规模扩张。对于它想解决的问题来说只能做到缓解而无法完全避免。我们需要一个更佳的方案,比如可以尝试随着一个对象的增大不断去分解它,像细胞进行有丝分裂一样。View model只是权宜之计。

其他社区也曾面临该问题

几年前 Rails 社区也曾遇到这种问题,他们也想出了解决方案,我们可以从中获得一些启示。首先他们有臃肿的controller以及几乎没什么内容的model。这种情况下很难进行测试,所以把所有的逻辑代码分解到model中,最终controller变得很简洁,model变得臃肿。复杂的model依赖于ActiveRecord和数据库,依旧难以测试,仍需要继续分割成更小的部分。

7 Patterns to Refactor Fat ActiveRecord Models 这篇博客受到8 Patterns to Help You Destroy Massive View Controller的影响,是这一系列想法下的产物。总而言之你仍需要将那些恼人的东西分割成小的单元,“转移下水道”的做法仅是缓解之计。

view model是一种完全无法应对现代编程挑战的做法,命名糟糕,对自己包含的功能不明确,最终面临和controller一样的问题。它只是对复杂情形的权宜之计,如果我们不去避免这种做法,很快又会面临同样的问题。

本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg

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

推荐阅读更多精彩内容