当前位置:网站首页>被误解的 MVC 和被神化的 MVVM(二)
被误解的 MVC 和被神化的 MVVM(二)
2022-08-03 16:50:00 【HelloWorld杰少】
MVVM 的历史
MVVM 是 Model-View-ViewModel 的简写。相对于 MVC 的历史来说,MVVM 是一个相当新的架构,MVVM 最早于 2005 年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出,并且应用在微软的软件开发中。当时 MVC 已经被提出了 20 多年了,可见两者出现的年代差别有多大。
MVVM 在使用当中,通常还会利用双向绑定技术,使得 Model 变化时,ViewModel 会自动更新,而 ViewModel 变化时,View 也会自动变化。所以,MVVM 模式有些时候又被称作:model-view-binder 模式。
具体在 iOS 中,可以使用 KVO 或 Notification 技术达到这种效果。
MVVM 的神化
在使用中,我发现大家对于 MVVM 以及 MVVM 衍生出来的框架(比如 ReactiveCocoa)有一种敬畏感。这种敬畏感某种程度上就像对神一样,这主要表现在我没有听到大家对于 MVVM 的任何批评。
我感觉原因首先是 MVVM 并没有很大程度上普及,大家对于新技术一般都不熟,进而不敢妄加评论。另外,ReactiveCocoa 本身上手的复杂性,也让很多人感觉到这种技术很高深难懂,进而加重了大家对它的「敬畏」。
MVVM 的作用和问题
MVVM 在实际使用中,确实能够使得 Model 层和 View 层解耦,但是如果你需要实现 MVVM 中的双向绑定的话,那么通常就需要引入更多复杂的框架来实现了。
对此,MVVM 的作者 John Gossman 的 批评 应该是最为中肯的。John Gossman 对 MVVM 的批评主要有两点:
第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。
第二点:对于过大的项目,数据绑定需要花费更多的内存。
某种意义上来说,我认为就是数据绑定使得 MVVM 变得复杂和难用了。但是,这个缺点同时也被很多人认为是优点。
ReactiveCocoa
函数式编程(Functional Programming)和响应式编程(React Programming)也是当前很火的两个概念,它们的结合可以很方便地实现数据的绑定。于是,在 iOS 编程中,ReactiveCocoa 横空出世了,它的概念都非常 新,包括:
函数式编程(Functional Programming),函数也变成一等公民了,可以拥有和对象同样的功能,例如当成参数传递,当作返回值等。看看 Swift 语言带来的众多函数式编程的特性,就你知道这多 Cool 了。
响应式编程(React Programming),原来我们基于事件(Event)的处理方式都弱了,现在是基于输入(在 ReactiveCocoa 里叫 Signal)的处理方式。输入还可以通过函数式编程进行各种 Combine 或 Filter,尽显各种灵活的处理。
无状态(Stateless),状态是函数的魔鬼,无状态使得函数能更好地测试。
不可修改(Immutable),数据都是不可修改的,使得软件逻辑简单,也可以更好地测试。哇,所有这些都太 Cool 了。当我看到的时候,我都鸡冻了!
我们应该客观评价 MVVM 和 ReactiveCocoa
但是但是,我突然想到,我好象只需要一个 ViewModel 而已,我完全可以简单地做一个 ViewModel 的工厂类或 Service 类就可以了,为什么要引入这么多框架?现有的 MVC 真的有那么大的问题吗?
直到现在,ReactiveCocoa 在国内外还都是在小众领域,没有被大量接受成为主流的编程框架。不只是在 iOS 语言,在别的语言中,例如 Java 中的 RxJava 也同样没有成为主流。
我在这里,不是想说 ReactiveCocoa 不好,也不是想说 MVVM 不好,而是想让大家都能够有一个客观的认识。ReactiveCocoa 和 MVVM 不应该被神化,它是一种新颖的编程框架,能够解决旧有编程框架的一些问题,但是也会带来一些新问题,仅此而已。如果不能使好的驾驭 ReactiveCocoa,同样会造成 Controller 代码过于复杂,代码逻辑不易维护的问题。
总结
有一些人总是追赶着技术,有什么新技术不管三七二十一立马就用,结果被各种坑。又有一些人,总是担心新技术带来的技术风险,不愿意学习。结果现在还有人在用 MRC 手动管理引用计数。而我想说,我们需要保持的是一个拥抱变化的心,以及理性分析的态度。在新技术的面前,不盲从,也不守旧,一切的决策都应该建立在认真分析的基础上,这样才能应对技术的变化。
边栏推荐
- [redis] cache penetration and cache avalanche and cache breakdown solutions
- Huawei, Lenovo, BAIC, etc. were selected as the first batch of training bases for "Enterprise Digital Transformation and Security Capability Improvement" by the Ministry of Industry and Information Te
- php之相似文章标题similar_text()函数使用
- C专家编程 第3章 分析C语言的声明 3.6 typedef int x[10]和#define x int[10]的区别
- JS中对象数组用sort按属性排序
- Cookie和Session的关系
- 【系统学习编程-编程入门-全民编程 视频教程】
- Adobe是什么?
- C专家编程 第1章 C:穿越时空的迷雾 1.7 编译限制
- phoenix创建映射表和创建索引、删除索引
猜你喜欢
附录A 程序员工作面试的秘密
C专家编程 第1章 C:穿越时空的迷雾 1.9 阅读ANSI C标准,寻找乐趣和裨益
Cookie和Session的关系
如何设计大电流九线导电滑环
[Unity Getting Started Plan] Basic Concepts (7) - Input Manager & Input Class
B站回应HR称核心用户是Loser;微博回应宕机原因;Go 1.19 正式发布|极客头条
The strongest distributed lock tool: Redisson
leetcode:202. 快乐数
TiKV & TiFlash accelerate complex business queries丨TiFlash application practice
高效的组织信息共享知识库是一种宝贵的资源
随机推荐
掌握Redis的Sentinel哨兵原理,可助你拿到25k的offer
面试突击:什么是粘包和半包?怎么解决?
九种方法!教你如何读取resources目录下的文件路径
uniapp的webview滑动缩放
[redis] cache penetration and cache avalanche and cache breakdown solutions
数字资产的价值激发:NFT 质押
After using Stream for many years, does collect still have these "saucy operations"?
11. Container With Most Water
Kubernetes 笔记 / 入门 / 生产环境 / 容器运行时
MySQL窗口函数 PARTITION BY()函数介绍
C语言04、操作符
LeetCode·72.编辑距离·动态规划
Which thread pool does Async use?
测试测试测试
protobuf 反射使用总结
如何在 DataWorks 中 写SQL语句监控数据的变化到达一定的值 进行提示
C专家编程 第3章 分析C语言的声明 3.4 通过图标分析C语言的声明
中小微企业如何简单便捷、低成本实现数字化?360视觉云有妙招
Halcon 小笔记 C# 图片是否有效
node连接mongoose数据库流程