当前位置:网站首页>被误解的 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 手动管理引用计数。而我想说,我们需要保持的是一个拥抱变化的心,以及理性分析的态度。在新技术的面前,不盲从,也不守旧,一切的决策都应该建立在认真分析的基础上,这样才能应对技术的变化。
边栏推荐
- 微信小程序 - 数组 push / unshift 追加后数组返回内容为数字(数组添加后打印结果为 Number 数值类型)
- security加密解密
- C专家编程 第1章 C:穿越时空的迷雾 1.8 ANSI C标准的结构
- 基于DMS的数仓智能运维服务,知多少?
- C专家编程 第1章 C:穿越时空的迷雾 1.9 阅读ANSI C标准,寻找乐趣和裨益
- [Unity Getting Started Plan] Basic Concepts (7) - Input Manager & Input Class
- 双指针/滑动窗口问题
- 【Metaverse系列一】元宇宙的奥秘
- Cookie和Session的关系
- node连接mongoose数据库流程
猜你喜欢
从零开始搭建MySQL主从复制架构
罗克韦尔AB PLC RSLogix5000中创建新项目、任务、程序和例程的具体方法和步骤
TiKV & TiFlash accelerate complex business queries丨TiFlash application practice
大型企业数据治理的现状和解决方案有哪些参考?_光点科技
掌握Redis的Sentinel哨兵原理,可助你拿到25k的offer
Detailed explanation of setting HiSilicon MMZ memory and OS memory
C专家编程 第3章 分析C语言的声明 3.7 typedef struct foo{... foo;}的含义
J9数字虚拟论:元宇宙的潜力:一股推动社会进步的力量
#yyds干货盘点# 面试必刷TOP101:两个链表的第一个公共结点
华为、联想、北汽等入选工信部“企业数字化转型和安全能力提升”首批实训基地
随机推荐
最强分布式锁工具:Redisson
MySQL窗口函数 PARTITION BY()函数介绍
掌握Redis的Sentinel哨兵原理,可助你拿到25k的offer
After using Stream for many years, does collect still have these "saucy operations"?
php之相似文章标题similar_text()函数使用
“68道 Redis+168道 MySQL”精品面试题(带解析),你背废了吗?
[Unity Getting Started Plan] Basic Concepts (6) - Sprite Renderer Sprite Renderer
【目标检测】Focal Loss for Dense Object Detection
Kubernetes 笔记 / 入门 / 生产环境 / 用部署工具安装 Kubernetes / 用 kubeadm 启动集群 / 安装 kubeadm
虹科分享 | 如何测试与验证复杂的FPGA设计(3)——硬件测试
Hannah荣获第六季完美童模全球总决赛全球人气总冠军
protobuf 中数据编码规则
303. Range Sum Query - Immutable
【带你了解SDN和网络虚拟化】
黄致绮 荣获第六季完美童模全球总决赛 全国总冠军
C专家编程 第3章 分析C语言的声明 3.4 通过图标分析C语言的声明
C专家编程 第3章 分析C语言的声明 3.8 理解所有分析过程的代码段
C语言04、操作符
MySQL窗口函数
[Unity Starter Plan] Making RubyAdventure01 - Player Creation & Movement