MVVM没你想象的那么的好
我写过很多有关于让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 一样的问题。它们只是当我们遇到复杂问题的临时补丁,如果我们忽略这些问题,在不久之后问题再次出现时,我们还是要解决同样的问题。
http://ios.jobbole.com/83759/
MVVM没你想象的那么的好的更多相关文章
- 全站 HTTPS 没你想象的那么简单
对自己无知这件事本身的无知真的挺可怕 认知偏差现象一直存在于我们每个人身上,谁也避免不掉,不过是有的人了解这件事儿,有的人不怎么知道而已,这就产生了「无知而不自知」的认知偏差.当然,这时候你自己忽悠自 ...
- Fragment中监听onKey事件,没你想象的那么难。
项目中越来越多的用到Fragment,在用Fragment取代TabHost的时候遇到了一个问题,我们都知道,TabHost的Tab为Activity实例,有OnKey事件,但是Fragment中没有 ...
- Don't Panic! KRACK 没你想象的那么糟
上海交通大学密码与计算机安全实验室(LoCCS)软件安全小组(GoSSIP)版权所有,转载请与作者取得联系! 著名的计算机学术安全会议CCS在2017年录用了一篇名为Key Reinstallatio ...
- "简单"的优化--希尔排序也没你想象中那么难
写在前边 大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数据结构这 ...
- mvvm小论(暂记)
广州-PC26(34627) 2:09:44 在android 线程最后用 handler = new Handler(); updateThread = new Runnabl ...
- DOMO1
以下是Demo首页的预览图 demo下载:http://www.eoeandroid.com/forum.php?mod=attachment&aid=NjE0Njh8ZTIyZDA2M2N8 ...
- Objective-C中的Block(闭包)
学习OC有接触到一个新词Block(个人感觉又是一个牛气冲天的词),但不是新的概念,不是新的东西.学过Javascript的小伙伴对闭包应该不陌生吧~学过PHP的应该也不陌生,在PHP5.3版本以后也 ...
- 自己实现苹果安装app动画
最近在学习CALayer相关动画,然后某一天突然发现苹果安装app这动画就很不错啊,所以就想自己实现下. 具体效果如图: 还是不试不知道一试吓一跳啊,这看上去简单的动画没我想象的那么简单. 首先这个动 ...
- Javascript:一个屌丝的逆袭
HTML负责结构, CSS负责展示, 而我(加上AJAX, JSON) 负责逻辑.于是前端编程三剑客形成了. http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExN ...
随机推荐
- 所读STL文章摘要集结
在网上看了一些STL相关文章,这里将它们的摘要进行集结,方便以后查找. 1.黄常标,林俊义,江开勇.快速成形中STL文件拓扑信息的快速建立.2004 摘要:在分析现有建立拓扑信息方法的基础上,提出基于 ...
- Android—— ListView 的简单用法及定制ListView界面
一.ListView的简单用法 2. 训练目标 1) 掌握 ListView 控件的使用 2) 掌握 Adapter 桥梁的作用 实现步骤: 1)首先新建一个项目, 并让ADT 自动帮我们创建好活动. ...
- IT兄弟连 JavaWeb教程 转发和重定向的区别
转发是在服务器端完成的:而重定向是在客户端完成的. 转发的速度快:而重定向的速度慢. 转发的是同一次请求:而重定向是两次不同的请求. 转发不会执行转发后的代码:而重定向会执行重定向后的代码. 转发地址 ...
- Luogu P1156 垃圾陷阱 【dp】By cellur925
题目传送门 这题...看上去浓浓的背包气息...但是并不好设计状态啊emmm. 我们考虑可能成为状态的量:高度.血量.时间.物品.看数据范围也猜到应该大概是个二维dp了w. 正确的状态设计之一:设$f ...
- wamp2.5版本配置多端口虚拟主机
1.保证httpd.conf下 LoadModule php5_module "D:/E/php/wamp/bin/php/php5.5.12/php5apache2_4.dll" ...
- elasticsearch接口开发(新)
此文在上一篇文章的基础上稍做了些许修改,主要在springboot整合ES后的包路径上,如下是新的目录结构 下面贴出代码 MyConfig.java package com.ylht.config; ...
- wordpress模板安装
wordpress的模板安装方法是: 1.把下载好的模板的目录整体复制到wordpress\wp-content\themes下面,不需要单独复制哪个文件 2.到后台的"外观"中选 ...
- new delete 创建回收细节
- Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)
题目链接: Hdu 5446 Unknown Treasure 题目描述: 就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.. ...
- Reduce实现
Reduce实现 参考 第一版 Array.prototype.fakeReduce = function (fn, base) { // this 指向原数组 // 拷贝数据, 更改指针方向 var ...