先道歉,可能有点标题党了。很早就看到过 MVVM 这个架构,一直没在工程里用过,但看到描述它的文章真是非常多。然而很想问:什么情况下适合用 MVVM ?一般比较常规的 app 真的需要用 MVVM 吗?
就从 objc 的这篇文章 来看,mvvm 大概有 3 个优点:
我想一条一条地来看:
业务逻辑可以放到 viewModel 层
我就想问,到底能有多少业务逻辑呀?像上面文章的举例,我们完全可以在 Person 类添加一个-(NSString*)nameDescription
方法,一个-(NSString*)birthdayText
方法。像这种拼一拼字符串的逻辑,放在 model 层是不是就足以解决问题了。
我想如果真是复杂的计算,也不适合在 app 端做;一般服务器都是把数据处理好, app 只要直接显示出来就行了。如果真是图片处理、视频合成这种的,也应该单独写个 service 类,本来也不该放在 viewController 里。这里所说的『业务逻辑』,我只能想到拼一拼字符串, timestamp 转成格式化时间等,这些东西真的有必要挪出来专门弄一个类吗。
我看到 viewController 大坨的代码,主要有就是 cell 和行高的路由分发和各种事件响应,我想 MVVM 并不能让它瘦身吧。
便于测试
这点很有道理,不过假如上面一点成立的话,光测这点简单逻辑也没大用,毕竟这些东西不容易错,不容易被不慎改坏,出 bug 也不容易出在这里。
数据更新的时候,视图可以自动更新
好吧,也许是我太 low ,但我见过 80% 的 viewController 都是这样的:显示 loading -> 发网络请求 -> 数据回来了,[tableView reloadData];
。这个『自动更新』也就是省了一句 [tableView reloadData];
而已,这个有那么重要吗。
比如更新视图一种比较麻烦的情况,比如用户从列表页进详情页,编辑了某种属性,回到列表页的时候要更新。然而 KVO 并不能解决这个问题啊。因为进到详情页,往往还需要再发网络请求,用户编辑属性的 model 跟列表里的已经不是一个对象了,也不会触发 KVO 。
综合上面这几条,我并不能想出 MVVM 特别有用的情况。但是有很多人都说,用了 ReactCocoa 真爽,效率提高 100 倍,代码省了很多,等等。
所以在此向大家请教,希望有朋友能给我一点提示,什么情况下用了 MVVM 确实有奇效。谢谢!
1
yuuko 2016-03-24 11:30:57 +08:00
有没有必要,看你有没有需求,没这个需求就没有必要,有这个需求就有必要
|
2
v1024 2016-03-24 11:48:48 +08:00
做 todo demo 很有用(手动斜眼
|
3
holy_sin 2016-03-24 12:12:33 +08:00 1
[[[[client
logInUser] flattenMap:^(User *user) { // Return a signal that loads cached messages for the user. return [client loadCachedMessagesForUser:user]; }] flattenMap:^(NSArray *messages) { // Return a signal that fetches any remaining messages. return [client fetchMessagesAfterMessage:messages.lastObject]; }] subscribeNext:^(NSArray *newMessages) { NSLog(@"New messages: %@", newMessages); } completed:^{ NSLog(@"Fetched all messages."); }]; 这个例子还比较经典,其实说到底就是封装吧 |
4
xi_lin 2016-03-24 12:15:52 +08:00
1. Model 和 ViewModel 是两回事。一个 ViewModel 可能涉及到多个 Model ,有些业务逻辑要跨 model 操作的,就可以放到 ViewModel 里。
3. 你需要看的是双向绑定 |
5
blacklee 2016-03-24 12:27:46 +08:00 via iPhone
RAC 确实很爽!非常爽!单独用就可以。
MVVM 还没用,看文档感觉一般。 对 View 的包装比较重要,尽量少让 View 的代码出现在 ViewController 里面。 |
7
hampotato OP @xi_lin 想问下一个 ViewModel 涉及到多个 Model 的时候,那这一个 ViewModel 对应一个 View 吗?
|
8
otakustay 2016-03-24 12:48:52 +08:00
@hampotato ViewModel 都是对应 View 的,基本上倾向于基于 View 设计 ViewModel 的结构
|
9
xi_lin 2016-03-24 12:58:33 +08:00
@hampotato 看你的粒度划分吧,我自己的习惯是一个 ViewController 对应一个 ViewModel 。复杂界面另说。
|
10
mko0okmko0 2016-03-24 13:02:39 +08:00
没有瀑布流的时候不使用复杂的设计和实作.
|
11
chaoxn 2016-03-24 13:44:00 +08:00
MVVM 还是和 RAC 结合起来的时候爽,单独 MVVM 不是很有必要
|
12
DingSoung 2016-03-24 13:52:17 +08:00
现在经常用啊, 模块分开了, 对外逻辑简单了
|
13
xhowhy 2016-03-24 13:55:43 +08:00
MVVM 本质上不是什么创新的东西, React 的思路才是,加了层 Virtual DOM
|
14
Wangxf 2016-03-24 13:56:23 +08:00 1
看需求吧,我就问你一个问题,假如现在有两个 input[type="text"],两个框旁边有个 span 或者说没有容器,你想要让自己随便在哪个框里输入数字,那个容器里会得到两个数相加的结果,是你你会怎么做?对比下传统的方式和 mvvm 框架来处理的方式你会发现生产效率提高了一大半
|
16
huanglexus 2016-03-24 14:56:45 +08:00
@holy_sin 然而这个例子跟 mvvm 一点关系都没有,这就是个 monad 的应用,跟 promise 一模一样
|
17
myrual 2016-03-24 15:04:20 +08:00
说效率提高 100 倍是扯淡的。
网络操作引发的 ui 更新方便是真的。 |
19
ChefIsAwesome 2016-03-24 16:24:36 +08:00 2
典型的就是购物车, TODO list 那样的东西。要解决的就是这么一个问题:同一块数据出现在 view 里的不同地方,这些地方又都能修改这个数据,怎么让这些地方同步起来。简单讲就是 mvc ,你修改 modal , modal 触发 change 事件, view 注册这个事件,把 view 上面跟 modal 相关的地方都给更新了。 mvvm 是更新 view 的一种方法,前端的 react 用的是另外一种方法。不管你选 mvvm 还是其他什么,基本上你要做的都只是更新 modal ,其他的交给框架来做。
|
20
wshcdr 2016-03-24 16:35:57 +08:00
viewModel 放显示逻辑...
|
21
hampotato OP @ChefIsAwesome 明白了~~ 购物车这个例子很有说服力~ 谢谢~~
|
22
hjc4869 2016-03-24 17:36:07 +08:00
展示算法用的 demo app 不需要用 MVVM 。
|
23
holy_sin 2016-03-24 18:13:10 +08:00
@ChefIsAwesome 有道理,按我的理解可以概括为数据驱动 UI
|
24
jesse_luo 2016-03-24 23:42:34 +08:00
我觉得是不是 MVVM 不重要,重要的是单向数据流(数据绑定)和逻辑拆分
|
25
jesse_luo 2016-03-24 23:44:49 +08:00
@ChefIsAwesome 对的,只要操作要展示的数据,剩下的都由一个可靠的框架实现
另外有的 VM 也会变得很大,所以横向拆分数据和逻辑也很重要 |
27
xhowhy 2016-03-29 14:25:21 +08:00
@longaiwp http://www.infoq.com/cn/articles/rethinking-mvc-mvvm
mvvm 微软早在 2005 年就推出了,又不是什么新奇东西,知道它为什么没火吗?除了微软本身生态不行之外, mvvm 只适合于简单的界面编程,因为: 1. 对于大型的图形应用程序,视图状态较多, ViewModel 的构建和维护的成本都会比较高。 2. 数据绑定的声明是指令式地写在 View 的模版当中的,这些内容是没办法去打断点 debug 的。 这种创新没多大用,明显没有考虑到覆盖普适和复杂的业务场景,而反观单向数据流,设计上反而更先进一些。 |
28
longaiwp 2016-03-29 16:40:01 +08:00
@xhowhy 这东西没火只是你的一厢情愿吧,那么多基于 MVVM 思想构建的程序,第一点我赞同,状态过多维护成本会很高,但是可测试性好太多了还有耦合度也下降了,第二点,这类内容的 debug 需求不高,你为什么要确定绑定是否失败?当然这个问题本身存在。最后一句, MVVM 不是万能的东西,但是也没你讲的那么不堪,它自有它的优点,但是这个世界写代码没有银弹
|
29
xhowhy 2016-03-29 17:08:45 +08:00
@longaiwp 不能 debug 就是深坑啊,如果你写码过超过 3 年,我想你应该可以理解啊。 React 的 JSX 至少还是可以调试的,因为数据流有据可循,但 MVVM 的 View 发生变化你却找不出是哪里的 M 改动导致的。
另外,如果 MVVM 是真火了,更早火起来的 Angular 为啥会被 React 后来追上? 本质没有变,当然就不能真的火啦 |
30
longaiwp 2016-03-30 07:50:26 +08:00
@xhowhy 你说的是另外一回事了,当然这也是 Redux 的优点,那就是可预测性,当然也一定程度提升了代码的复杂度,当然对于大型的项目里,这种可预测性对于维护是很重要的。而且 Angular 和 React 比较起来, Angular 不是因为 MVVM 才被追上。不然我要问,为什么 React 会被 Vue 后来追上?
|
32
zhigang1992 2016-04-04 22:00:17 +08:00
其实规模稍微大一点的应用还是有一堆一堆的业务逻辑的。
服务器给出、接受的往往在设计上的时候考虑的是数据本身的属性,而不是按照界面、交互来设计的。 而这里面的转化往往不仅仅是一个 Mapper 能搞定的。 我个人的理解就是 ViewModel 其实算一个 View / Interaction 和 Model 之间的桥梁。 这种情况下可测就非常重要, UIView, UIViewController 测试起来太恼火了。往往导致后面大家都不写这些逻辑的测试。 ViewModel 应该于 UIKit 隔离开来,这样就又一个好处, 在用 Xamarin 之类的东西做跨平台应用的时候, 一套 ViewModel 可以给 iOS 和 Android 共享代码,只要在 View 层做不同的绑定和交互就可以。 |
33
kitalphaj 2016-04-05 08:48:12 +08:00
看了半天没看懂,明明是在说 MVVM ,全都扯到 React 上去了。。。就算这俩经常一起用也不能混为一谈啊。单独用 React 完全没有问题,而且现在用了 Swift 的面向协议的编程后,完全可以把很多显示逻辑放到 extension 里面。
|