真的有必要用 MVVM 吗?

2016-03-24 11:21:33 +08:00
 hampotato

先道歉,可能有点标题党了。很早就看到过 MVVM 这个架构,一直没在工程里用过,但看到描述它的文章真是非常多。然而很想问:什么情况下适合用 MVVM ?一般比较常规的 app 真的需要用 MVVM 吗?

就从 objc 的这篇文章 来看,mvvm 大概有 3 个优点:

  1. 业务逻辑可以放到 viewModel 层
  2. 便于测试
  3. 视图与数据绑定,数据更新的时候,视图可以自动更新(如果用 ReactCocoa 之类 KVC 绑定的话)。

我想一条一条地来看:

  1. 业务逻辑可以放到 viewModel 层

    我就想问,到底能有多少业务逻辑呀?像上面文章的举例,我们完全可以在 Person 类添加一个-(NSString*)nameDescription方法,一个-(NSString*)birthdayText方法。像这种拼一拼字符串的逻辑,放在 model 层是不是就足以解决问题了。

    我想如果真是复杂的计算,也不适合在 app 端做;一般服务器都是把数据处理好, app 只要直接显示出来就行了。如果真是图片处理、视频合成这种的,也应该单独写个 service 类,本来也不该放在 viewController 里。这里所说的『业务逻辑』,我只能想到拼一拼字符串, timestamp 转成格式化时间等,这些东西真的有必要挪出来专门弄一个类吗。

    我看到 viewController 大坨的代码,主要有就是 cell 和行高的路由分发和各种事件响应,我想 MVVM 并不能让它瘦身吧。

  2. 便于测试

    这点很有道理,不过假如上面一点成立的话,光测这点简单逻辑也没大用,毕竟这些东西不容易错,不容易被不慎改坏,出 bug 也不容易出在这里。

  3. 数据更新的时候,视图可以自动更新

    好吧,也许是我太 low ,但我见过 80% 的 viewController 都是这样的:显示 loading -> 发网络请求 -> 数据回来了,[tableView reloadData];。这个『自动更新』也就是省了一句 [tableView reloadData]; 而已,这个有那么重要吗。

    比如更新视图一种比较麻烦的情况,比如用户从列表页进详情页,编辑了某种属性,回到列表页的时候要更新。然而 KVO 并不能解决这个问题啊。因为进到详情页,往往还需要再发网络请求,用户编辑属性的 model 跟列表里的已经不是一个对象了,也不会触发 KVO 。

综合上面这几条,我并不能想出 MVVM 特别有用的情况。但是有很多人都说,用了 ReactCocoa 真爽,效率提高 100 倍,代码省了很多,等等。

所以在此向大家请教,希望有朋友能给我一点提示,什么情况下用了 MVVM 确实有奇效。谢谢!

6021 次点击
所在节点    iDev
33 条回复
hampotato
2016-03-24 17:31:41 +08:00
@ChefIsAwesome 明白了~~ 购物车这个例子很有说服力~ 谢谢~~
hjc4869
2016-03-24 17:36:07 +08:00
展示算法用的 demo app 不需要用 MVVM 。
holy_sin
2016-03-24 18:13:10 +08:00
@ChefIsAwesome 有道理,按我的理解可以概括为数据驱动 UI
jesse_luo
2016-03-24 23:42:34 +08:00
我觉得是不是 MVVM 不重要,重要的是单向数据流(数据绑定)和逻辑拆分
jesse_luo
2016-03-24 23:44:49 +08:00
@ChefIsAwesome 对的,只要操作要展示的数据,剩下的都由一个可靠的框架实现
另外有的 VM 也会变得很大,所以横向拆分数据和逻辑也很重要
xhowhy
2016-03-29 14:19:46 +08:00
@longaiwp 就你呵呵,就你呱呱叫
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 的。

这种创新没多大用,明显没有考虑到覆盖普适和复杂的业务场景,而反观单向数据流,设计上反而更先进一些。
longaiwp
2016-03-29 16:40:01 +08:00
@xhowhy 这东西没火只是你的一厢情愿吧,那么多基于 MVVM 思想构建的程序,第一点我赞同,状态过多维护成本会很高,但是可测试性好太多了还有耦合度也下降了,第二点,这类内容的 debug 需求不高,你为什么要确定绑定是否失败?当然这个问题本身存在。最后一句, MVVM 不是万能的东西,但是也没你讲的那么不堪,它自有它的优点,但是这个世界写代码没有银弹
xhowhy
2016-03-29 17:08:45 +08:00
@longaiwp 不能 debug 就是深坑啊,如果你写码过超过 3 年,我想你应该可以理解啊。 React 的 JSX 至少还是可以调试的,因为数据流有据可循,但 MVVM 的 View 发生变化你却找不出是哪里的 M 改动导致的。
另外,如果 MVVM 是真火了,更早火起来的 Angular 为啥会被 React 后来追上?
本质没有变,当然就不能真的火啦
longaiwp
2016-03-30 07:50:26 +08:00
@xhowhy 你说的是另外一回事了,当然这也是 Redux 的优点,那就是可预测性,当然也一定程度提升了代码的复杂度,当然对于大型的项目里,这种可预测性对于维护是很重要的。而且 Angular 和 React 比较起来, Angular 不是因为 MVVM 才被追上。不然我要问,为什么 React 会被 Vue 后来追上?
xhowhy
2016-03-30 14:36:32 +08:00
@longaiwp no no no ,没提到 redux ,我说的主要是 React 。。另外 Vue 是什么鬼
zhigang1992
2016-04-04 22:00:17 +08:00
其实规模稍微大一点的应用还是有一堆一堆的业务逻辑的。

服务器给出、接受的往往在设计上的时候考虑的是数据本身的属性,而不是按照界面、交互来设计的。

而这里面的转化往往不仅仅是一个 Mapper 能搞定的。

我个人的理解就是 ViewModel 其实算一个 View / Interaction 和 Model 之间的桥梁。

这种情况下可测就非常重要, UIView, UIViewController 测试起来太恼火了。往往导致后面大家都不写这些逻辑的测试。

ViewModel 应该于 UIKit 隔离开来,这样就又一个好处,

在用 Xamarin 之类的东西做跨平台应用的时候,

一套 ViewModel 可以给 iOS 和 Android 共享代码,只要在 View 层做不同的绑定和交互就可以。

<amp-youtube data-videoid="dHlwC-UNkxs" layout="responsive" width="480" height="270"></amp-youtube>
kitalphaj
2016-04-05 08:48:12 +08:00
看了半天没看懂,明明是在说 MVVM ,全都扯到 React 上去了。。。就算这俩经常一起用也不能混为一谈啊。单独用 React 完全没有问题,而且现在用了 Swift 的面向协议的编程后,完全可以把很多显示逻辑放到 extension 里面。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/265978

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX