MVVM没你想象的那么的好
2016-01-16 19:20:22 | 来源:玩转帮会 | 投稿:佚名 | 编辑:小柯

原标题:MVVM没你想象的那么的好

  • 本文由cocoaChina译者 陈溪 翻译

  • 作者:Soroush Khanlou

  • 原文:MVVM is Not Very Good

我写过很多有关于让View Controller 更易于理解的文章,其中一种比较常见的模式就是Model-View-ViewModel(MVVM)。 我认为MVVM 是一种非常容易让人混淆的 anti-pattern(反面模式设计)。View models是很糟糕的名字,它只是优秀架构之路上的权宜之计。我们的团体将从这种模式过度到更好的模式。

MVVM 是一个很糟糕的名字

名字很重要。理想的情况下,一个名字能够有效地表达这个对象是什么,它扮演了什么样的角色,以及如何使用它等。View model作为一个名字,没有起到任何的作用。

以我的经验来看,考虑到view model的抽象性,它实际上代表了两种迥然不同的模式

第一种 “view model” 是 “model for the view”。这是一个dumb object(在Swift中绝对是一个结构体) 用来传递 view 给它的子视图。它不应该包含任何逻辑甚至是任何方法。这跟UILabel包含string,或者UIImageView包含Image,自定义profileView包含profileViewModel 是一样的道理。它直接传递给你的ProfileView,最重要的是,它允许你将子视图私有化,而不是将子视图暴露在外面。这是一个非常好的方法。我见过一种叫 view data 的模式,我非常喜欢这种模式,因为它将自己从定义模糊不清的”view model” 中剥离出来了。

View model 同时也一种介于model object和view controller之间模糊的、抽象的名词。它处理数据展示、网络请求获取数据、表单验证和你认为可以放在这里的其他任务。这种万金油风格的对象主要用来减轻控制器的压力。但是最终,你只是多建立了一个能够让你将任务分工倒进去的容器。

MVVM 承担了更多的责任

这种缺乏具体内涵的名字导致了这个类负责的东西无限地增长。那么什么样的功能才应该放在 view model 中呢?没人知道! 随便写就是了。

我们来看一些例子

  • Let’s discuss MVVM for iOS 这篇文章展示了view model 中的网络数据模型 ,推荐你在里边添加验证和展示逻辑。

  • Introduction to MVVM 这篇文章展示了如何将表示逻辑放入视图模型中,同时引发了一个问题–为什么它不叫 Presenter?

  • COCOA SAMURAI?这篇告诉你应该用view model来上传数据并绑定ReactiveCocoa.

  • ReactiveCocoa and MVVM, an Introduction 这篇使用view model 来表格验证和获取数据。

  • Model-View-ViewModel for iOS 这篇文章特别建议你将“miscellaneous code”(“无法明确定义的代码”) 放入到view model 中。

View Model非常适用于存放用户输入的验证逻辑,视图的表示逻辑, 网络请求的初始化和其它“miscellaneous code ”的地方。

没人知道“view model”代表着什么,所以人们无法在view model 应该包含什么内容这一问题上达成一致。view model 这个概念本身就太抽象了。这些作者在Validator class、Presenter class 或者 Fetcher class 该做哪些事和不该做哪些事上有不同的观点。这些都是有着明确定义的好名字。

假设一个同样的名字,在不同的对象中有着迥然不同的任务分工,那么它只会混淆读代码的人。如果我们无法在view model 的作用上达成一致,那么将这些不同作用的“view model”取成同一个名字又由什么好处呢?

我们已知的规律中已经面临了一个同样的挑战,并且我们发现“controller”的名字定义太广泛了,它能够包含很多小的任务 .

你完全可以给你自己的类定义一个你想要的名字!选一个好点的名字

MVVM并没有改变你代码的结构

最后,view models 本质上并没有改变你app的结构。这两幅图有什么区别?(source)

你不需要高级的图形理论就可以看出他们基本上是完全一样的。

我所知道这个模式最清楚的地方就是: 它将view controller 中的(view controller不是一个你拥有的对象,因为它是Apple class 的一个子类) 代码移动到了你拥有的view model 中。这样view controller 就很容易的能够聚焦view生命周期时间。尽管这样,我们的代码还是大量的聚集在一起,它只是从view controller 移动到了 view model 中而已。

因为view model 只有一个,我们还没有解决这个复杂的问题。如果你创建一个view model 来避免你的控制器过于臃肿,那么如果你的app代码又增加了一倍要怎么办?或许到那时候,我们可以加一个controller-model.

这种view model 解决方法不是很好,它只是在问题上贴了一个创可贴,问题还会继续出现。我们需要一个更好的,能从根本上解决问题的办法。就像一个能够在对象变得更大时,你能够对其进行持续性的划分,好比正在进行有丝分裂的细胞。view model它只是个一次性的补丁。

其他的团体已经经历过这样的问题

Rails community 在几年前就经历过这个问题,我们能够从他们的故事中有所借鉴。首先,他们controller非常臃肿 ,除了persistence(持久性数据)外,几乎是一个空的模型。这样的代码几乎无法测试,于是他们将所有的逻辑移动到了model中,这样就有了简洁的controller和臃肿的model。由于臃肿的model依靠于ActiveRecord, 这样的话数据库依旧很难测试并且需要拆分成很小的单元。

博客里面已经贴出了像 7 Patterns to Refactor Fat ActiveRecord Models 这篇文章 (给了我写8 Patterns to Help You Destroy Massive View Controller这篇文章的灵感),这是上述思维方式的产品例子。最终,你将持续将你的核心分割成小的单元,那么移动你的代码时就能够有效的划分到对应的区域。

View model作为一种解决方法,并不适用于现代编程模式的变化。他们是一种定义不清的结构,不知道应该包含什么,这就导致了它们会遇到和view controller 一样的问题。它们只是当我们遇到复杂问题的临时补丁,如果我们忽略这些问题,在不久之后问题再次出现时,我们还是要解决同样的问题。

  • 本文仅用于学习和交流目的,转载请注明文章译者、作者、出处以及本文链接。

  • 感谢博文视点对本期翻译活动的支持

tags:

上一篇  下一篇

相关:

源码推荐(01.11B):iOS项目分层,Widget手机任务栏

iOS项目分层(上传者:踏浪帅)主项目中的分层主要包含四个模块,Main(主要)、Expand(扩展)、Resource(照片)、

通过Moya+RxSwift+Argo完成网络请求

作者:@请叫我汪二 授权本站转载。最近在新项目中尝试使用 Moya+RxSwift+Argo 进行网络请求和解析,感觉还阔

Loading动画外篇·圆的不规则变形

一款Loading动画的实现思路系列已经结束了,非常感谢大家的捧场。看过本系列的同学可能还记得,我对原动效做

苹果mac怎么共享屏幕?mac屏幕共享设置教程

苹果mac怎么共享屏幕?OS X 自带屏幕共享功能,支持拖拽以及文本拷贝,操作还相当简单,仅需要点几个按钮就

觅海宝怎么样?觅海宝好不好?

  觅海宝怎么样?觅海宝好不好?觅海宝是什么呢?这是一个中欧海淘跨境电商平台,由英国贸易投资总署和英

RightFont怎么用?字体管理工具RightFont使用教程

RightFont是一款Mac平台的字体管理软件,很多设计师们都需要使用到它,今天PC6小编就为大家带来一篇详尽的R

Web端PHP代码函数覆盖率测试解决方案

1. 关于代码覆盖率衡量代码覆盖率有很多种层次,比如行覆盖率,函数/方法覆盖率,类覆盖率,分支覆盖率等等

我从1万小时编程中学到了什么

本文由玩赚乐(www.banghui.org)– 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

回顾2015年最大的7个App趋势

本文由玩赚乐(www.banghui.org)– 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

Android性能优化之加快应用启动速度

应用的启动启动方式通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动。1、冷启动:当启动应用时,

站长推荐: