我写过很多有关于让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 中呢?没人知道! 随便写就是了。

我们来看一些例子

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 一样的问题。它们只是当我们遇到复杂问题的临时补丁,如果我们忽略这些问题,在不久之后问题再次出现时,我们还是要解决同样的问题。

http://ios.jobbole.com/83759/

MVVM没你想象的那么的好的更多相关文章

  1. 全站 HTTPS 没你想象的那么简单

    对自己无知这件事本身的无知真的挺可怕 认知偏差现象一直存在于我们每个人身上,谁也避免不掉,不过是有的人了解这件事儿,有的人不怎么知道而已,这就产生了「无知而不自知」的认知偏差.当然,这时候你自己忽悠自 ...

  2. Fragment中监听onKey事件,没你想象的那么难。

    项目中越来越多的用到Fragment,在用Fragment取代TabHost的时候遇到了一个问题,我们都知道,TabHost的Tab为Activity实例,有OnKey事件,但是Fragment中没有 ...

  3. Don't Panic! KRACK 没你想象的那么糟

    上海交通大学密码与计算机安全实验室(LoCCS)软件安全小组(GoSSIP)版权所有,转载请与作者取得联系! 著名的计算机学术安全会议CCS在2017年录用了一篇名为Key Reinstallatio ...

  4. "简单"的优化--希尔排序也没你想象中那么难

    写在前边 大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数据结构这 ...

  5. mvvm小论(暂记)

    广州-PC26(34627) 2:09:44 在android 线程最后用 handler = new Handler();            updateThread = new Runnabl ...

  6. DOMO1

    以下是Demo首页的预览图 demo下载:http://www.eoeandroid.com/forum.php?mod=attachment&aid=NjE0Njh8ZTIyZDA2M2N8 ...

  7. Objective-C中的Block(闭包)

    学习OC有接触到一个新词Block(个人感觉又是一个牛气冲天的词),但不是新的概念,不是新的东西.学过Javascript的小伙伴对闭包应该不陌生吧~学过PHP的应该也不陌生,在PHP5.3版本以后也 ...

  8. 自己实现苹果安装app动画

    最近在学习CALayer相关动画,然后某一天突然发现苹果安装app这动画就很不错啊,所以就想自己实现下. 具体效果如图: 还是不试不知道一试吓一跳啊,这看上去简单的动画没我想象的那么简单. 首先这个动 ...

  9. Javascript:一个屌丝的逆袭

    HTML负责结构, CSS负责展示, 而我(加上AJAX, JSON) 负责逻辑.于是前端编程三剑客形成了. http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExN ...

随机推荐

  1. java类成员访问权限总结(private,default,protected,public)

  2. 并不对劲的p4449于神之怒加强版

    题目大意 给定\(t,k(t\leq2000,k\leq5*10^6)\) \(t\)组询问,每组给出\(n,m(n,m\leq5*10^6)\)求$\sum_{i=1}^n \sum_{j=1}^m ...

  3. WIN7开机自动登录设置

    WIN7开机自动登录设置 1    执行rundll32 netplwiz.dll,UsersRunDll 开始菜单中找到运行并单击运行:如下图1所示                         ...

  4. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 21. Model 验证 Again

    深入的将Model验证 手动添加验证的错误 view里面显示每个属性的验证错误信息 显示整个model级别错误 自定义验证 如果业务逻辑需要比较复杂的验证.而且这个验证逻辑可能到处复用的话就应该考虑使 ...

  5. 微信公众号开发及时获取当前用户Openid及注意事项

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及 ...

  6. 让 Ocelot 与 asp.net core “共存”

    让 Ocelot 与 asp.net core "共存" Intro 我们的 API 之前是一个单体应用,各个模块的服务是通过 Assembly 集成在一起,最后部署在一个 web ...

  7. adb相关

    --------------------------------------------- adb logcat |find "nafio" >c:/logcat.txt 另 ...

  8. win10家庭版安装

    https://www.microsoft.com/zh-cn/software-download/windows10ISO https://www.2cto.com/os/201704/621770 ...

  9. bzoj 2131: 免费的馅饼【dp+树状数组】

    简单粗暴的dp应该是把馅饼按时间排序然后设f[i]为i接到馅饼能获得的最大代价,转移是f[i]=max(f[j])+v[i],t[j]<=t[i],2t[i]-2t[j]>=abs(p[i ...

  10. bzoj 2440: [中山市选2011]完全平方数【莫比乌斯函数+二分】

    二分答案,然后用莫比乌斯函数作为容斥系数,计算当前枚举的mid内有几个满足要求的数 #include<iostream> #include<cstdio> #include&l ...