真的有必要用 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 确实有奇效。谢谢!

5907 次点击
所在节点    iDev
33 条回复
yuuko
2016-03-24 11:30:57 +08:00
有没有必要,看你有没有需求,没这个需求就没有必要,有这个需求就有必要
v1024
2016-03-24 11:48:48 +08:00
做 todo demo 很有用(手动斜眼
holy_sin
2016-03-24 12:12:33 +08:00
[[[[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.");
}];

这个例子还比较经典,其实说到底就是封装吧
xi_lin
2016-03-24 12:15:52 +08:00
1. Model 和 ViewModel 是两回事。一个 ViewModel 可能涉及到多个 Model ,有些业务逻辑要跨 model 操作的,就可以放到 ViewModel 里。
3. 你需要看的是双向绑定
blacklee
2016-03-24 12:27:46 +08:00
RAC 确实很爽!非常爽!单独用就可以。
MVVM 还没用,看文档感觉一般。
对 View 的包装比较重要,尽量少让 View 的代码出现在 ViewController 里面。
hampotato
2016-03-24 12:32:08 +08:00
@holy_sin 嗯嗯,看了下 RC 的这个例子,这样写确实不错~
hampotato
2016-03-24 12:33:00 +08:00
@xi_lin 想问下一个 ViewModel 涉及到多个 Model 的时候,那这一个 ViewModel 对应一个 View 吗?
otakustay
2016-03-24 12:48:52 +08:00
@hampotato ViewModel 都是对应 View 的,基本上倾向于基于 View 设计 ViewModel 的结构
xi_lin
2016-03-24 12:58:33 +08:00
@hampotato 看你的粒度划分吧,我自己的习惯是一个 ViewController 对应一个 ViewModel 。复杂界面另说。
mko0okmko0
2016-03-24 13:02:39 +08:00
没有瀑布流的时候不使用复杂的设计和实作.
chaoxn
2016-03-24 13:44:00 +08:00
MVVM 还是和 RAC 结合起来的时候爽,单独 MVVM 不是很有必要
DingSoung
2016-03-24 13:52:17 +08:00
现在经常用啊, 模块分开了, 对外逻辑简单了
xhowhy
2016-03-24 13:55:43 +08:00
MVVM 本质上不是什么创新的东西, React 的思路才是,加了层 Virtual DOM
Wangxf
2016-03-24 13:56:23 +08:00
看需求吧,我就问你一个问题,假如现在有两个 input[type="text"],两个框旁边有个 span 或者说没有容器,你想要让自己随便在哪个框里输入数字,那个容器里会得到两个数相加的结果,是你你会怎么做?对比下传统的方式和 mvvm 框架来处理的方式你会发现生产效率提高了一大半
longaiwp
2016-03-24 14:45:31 +08:00
@xhowhy 你这个想法,我只能说呵呵
huanglexus
2016-03-24 14:56:45 +08:00
@holy_sin 然而这个例子跟 mvvm 一点关系都没有,这就是个 monad 的应用,跟 promise 一模一样
myrual
2016-03-24 15:04:20 +08:00
说效率提高 100 倍是扯淡的。
网络操作引发的 ui 更新方便是真的。
hampotato
2016-03-24 15:50:54 +08:00
@Wangxf 有道理,有些输入验证的时候用得上。有点像 angular 的优势
ChefIsAwesome
2016-03-24 16:24:36 +08:00
典型的就是购物车, TODO list 那样的东西。要解决的就是这么一个问题:同一块数据出现在 view 里的不同地方,这些地方又都能修改这个数据,怎么让这些地方同步起来。简单讲就是 mvc ,你修改 modal , modal 触发 change 事件, view 注册这个事件,把 view 上面跟 modal 相关的地方都给更新了。 mvvm 是更新 view 的一种方法,前端的 react 用的是另外一种方法。不管你选 mvvm 还是其他什么,基本上你要做的都只是更新 modal ,其他的交给框架来做。
wshcdr
2016-03-24 16:35:57 +08:00
viewModel 放显示逻辑...

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

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

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

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

© 2021 V2EX