首页 > 其他分享 >MVVM的优点和缺点

MVVM的优点和缺点

时间:2023-01-01 11:07:21浏览次数:53  
标签:控制器 MVVM 视图 优点 缺点 Model 页面 View


MVVM的典型开源项目下载地址:​​https://github.com/kopuCoder/SXNews。​​​ MVVM( Model-View-ViewModel子控件的事件驱动模型),也就是轻量级的控制器架构。它本质上就是MVC的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。Model就是Entity,定义数据;View实现视图 UI;ViewModel负责请求发送及业务逻辑;UIViewController只负责生成数据(Model),View(视图 UI),ViewModel(请求发送及业务逻辑)三者的对象与协调他们完成具体的页面。
软件开发人员的两种典型错误思维
1.头脑风暴。
2.盲目反对。
纯粹的头脑风暴会让你只看到软件方案和架构的优点,避而不谈它的缺点。软件不可能永远存在云上,它会落地的,当它落地时,会出现这样和那样的问题。
盲目的反对更要不得,这也不行,那也不行,只看一种方案和架构的缺点,看不到优点,那不是什么都不要做了。每个人由于习惯使然会偏向这两种做法,需要从心理上克服这种偏颇,采用包容的心态。
苹果客户端开发的三种境界
1.无明显架构的无序开发(新人的初始状态),想的是MVC架构开发,由于技术知识不足或懒惰,只追求速度,把一个页面所有的逻辑和控件都在该页面的控制器里完成,不去抽象控件,不去抽象模块。一个xib和控制器包打一个页面的天下。这样的架构和思维要不得,可以当自己学习新技术使用,不要用到具体的软件开发中去。
2.MVC(Model View Controller)架构开发,它是苹果推荐的开发模式,它把页面分成三部分:数据模型,页面视图,页面控制器。一个页面被分成多个小视图,一个页面共享一个数据模型,只是这个数据模型只被控制器操作,不被各个子视图处理。这个架构看起来整洁多了,控制器的复杂度降低的很多,页面的显示单元被分配到各个视图去显示,控制器专注与数据的加工与处理,部分解放了控制器,使它的功能更集中,更紧凑,更小。数据模型,页面视图,页面控制器各个独立,各司其职。这就是重量级视图控制的特点。它看起来简单,更容易理解,所有的逻辑在视图控制器里处理。一个页面一般分三个文件夹:页面文件夹(存放页面控制器和其子文件夹),页面文件夹下的model文件夹,页面文件夹下的view文件夹。想找页面间的逻辑就去页面控制器里找,想看页面显示元素就在view文件夹下寻找。你发现数据文件很小,只是数据存储和转换,这符合数据单一性原则;视图部分也很小,只是数据的显示,完全不自主;控制器部分仍然摆脱不了过于庞大的弊病。他们就像一个人一样头重而且庞大,脚轻,身子小。看到这些你就知道这种开发架构需要进化的方向:强化控制器的重要性,减轻它的体积,把不属于它的非核心部分迁移到类似视图的那一部分去,在保证数据的定义性上增加它的功能和作用。取消使用单例组装http请求的做法(单例像类一样常驻内存,无形中增加类内存的开销。虽然它做到了统一管理http请求的作用,但是不符合那个页面的请求那个页面管理请求的原则)。让从控制器分化出来的这一部分功能给View,http请求封装为一个新操作类。

3.MVVM( Model View-Model Controller View)就是MVC设计模式的更先进进化,符合它进化的方向。每个人对MVVM了解不同和使用技术不同,最终实现的MVVM架构也不同。
数据源被强化,不单只是请求过来的数据还包括,数据在本页面应该处于的状态(例如:根据请求,支付页面是企业支付,不需要显示第三方支付选择框,model增加了这样的状态。当然这样的状态可以改变,用户重新选择了支付方式,选择个人支付,该状态要根据用户的行为而改变。),数据源对象在本页面或本模块中共享,一旦一个地方改变,本页面或模块中的所有数据源的内容都改变,保证了数据的一致性。它的全局共享性是它的一大特色。
从控制器分离出来的非页面间关系部分和http请求部分,产生请求操作类.它可以被控制器调用,也可以被view调用。它负责数据数据请求参数的组装,甚至上次请求的暂存,服务器请求过来的数据转化为数据源数据,进行简单数据处理。我们称它为View-Model。一个页面可以有一个View-Model,也可以有多个View-Model,这个可以根据页面的复杂度和View(调用View-Model的View)是否在其它页面重用。若有View调用请求对象发送请求并且被其它页面重用该View,那么该View不能共享数据源。View-Model一般持有本页面或本模块的共享数据源。
控制器专注于自己的核心功能:页面的跳转,跨本页面多个视图的操作,数据源数据的初始化,从上一个页面接收数据转化为本页面的数据源(有的页面不发送请求只是显示数据,有的页面需要上也个页面接收关键字段(如“订单号)作为本页面请求的参数),子视图页面的创建和布局,子视图页面的block函数,状态栏,导航栏,页面跳转方式(有的页面需要跳转后销毁本页面—地图页面);有的页面出现后需要常驻内存,不能销毁本页面–Tabbar页面),在dealloc中销毁移除通知。除了这些核心事件外,其它的都可以移置到View或View-Model中处理。控制器持有本页面或本模块的共享数据源。
控制器相对的并不是只有父类为UIViewController的类才是控制器。当也个页面过于复杂,被分成了多个层次时,可以通过在[[[UIApplication sharedApplication] delegate] window]增加view。这个新增加的View本身就和控制器的功能一样。这个可以做到一层页面就是一个控制器。
当然也可以下面的方法创建window。这个window也是和控制器一致。 self.currentWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, FULL_WIDTH, FULL_HEIGHT)];
self.currentWindow.windowLevel = UIWindowLevelStatusBar;
self.currentWindow.opaque = NO;
[self.currentWindow makeKeyAndVisible];若用创建window的方法创建视图控制器时需要在销毁这个window时调用[[[[UIApplication sharedApplication] delegate] window] makeKeyAndVisible];来使原来的window显示。由于该方法实际上向主线程发送的一个通知,等刷新UI线程调用了响应的处理才执行,就是它是异步执行的,所以当页面首次加载时有可能页面显示不出来的情况。所以这种方法建议慎用,采用上一种方法更安全。
View增强了两大功能:持有全局数据源,根据数据源进行显示和布局;可以直接调用请求对象发送请求,来刷新数据或页面跳转。可以看到View已经具有部分控制器的功能(调用View-Model发送http请求,刷新页面),并且View根据抽象的需要可以在不同页面或模块间共享使用。
MVVM一般包含页面(或模块)总文件夹,Entity文件夹(model对象或模块内的编译宏),View文件夹(视图文件,该文件夹下可能包含子ViewModel文件夹),图片库(Assets.xcassets),ViewController文件夹(控制器对象),ViewModel文件夹(http请求对象)。除了这个5个基本文件夹外还可能包含序列化model的文件夹。
MVVM设计模式的优点
1.双向绑定技术,当Model变化时,View-Model会自动更新,View也会自动变化。很好做到数据的一致性,不用担心,在模块的这一块数据是这个值,在另一块就是另一个值了。所以 MVVM模式有些时候又被称作:model-view-binder模式。
2.View的功能进一步的强化,具有控制的部分功能,若想无限增强它的功能,甚至控制器的全部功几乎都可以迁移到各个View上(不过这样不可取,那样View干了不属于它职责范围的事情)。View可以像控制器一样具有自己的View-Model.
3.由于控制器的功能大都移动到View上处理,大大的对控制器进行了瘦身。不用再为看到庞大的控制器逻辑而发愁了。
4.可以对View或ViewController的数据处理部分抽象出来一个函数处理model。这样它们专职页面布局和页面跳转,它们必然更一步的简化。
【长篇高能】ReactiveCocoa 和 MVVM 入门(​​​http://www.cocoachina.com/ios/20150526/11930.html)就是MVVM设计模式头脑风暴提唱者。其实它没有那么神,它也有很多固有的缺点,而且有的优点其实也是缺点,并且不容易改进。​​​ MVVM设计模式的缺点
第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。
第二点:一个大的模块中,model也会很大,虽然使用方便了也很容易保证了数据的一致性,当长期持有,不释放内存,就造成了花费更多的内存。
第三点:数据双向绑定不利于代码重用。客户端开发最常用的重用是View,但是数据双向绑定技术,让你在一个View都绑定了一个model,不同模块的model都不同。那就不能简单重用View了。
被误解的MVC和被神化的MVVM这篇文章是MVVM彻头彻尾的反对者,好像该设计模式一文不值。我只能说他太偏激了,只顾着指责,没有看到他最显然的优点和改进。​ MVVM设计模式的优缺点之我见及改进
MVVM更高级更先进表现在解放了控制器(Controller),就是轻量级控制器。这个批评者也没有否定。MVVM不影响代码重用,其实抽象出来的一个一个小View就是为了代码重用的。反对者所谓的把网络请求封装到类里也就是View-Model。
其实对它贬低最多的只剩下集优缺点于一身的双向绑定技术。那么他们也不治之症,也可以改进。
对于调试困难的问题,确实存在,可以通过日志系统来定位,对数据被修改的地方进行敏感的地方进行日志打印。不会你的软件没有日志系统吧?
对于影响内存问题,你可以通过划分模块时,把一个页面或两到三个页面划分为一个模块,那样应用的model也不大,内存开销很小。我大都把每个页面多划分一个模块,减少耦合度,软件开发的高内聚低耦合的设计思想大家都懂吧!若把一个项目的数据都整合到一个面面俱到的model, 那除非傻子才那么做,就是那样做了,那也不符合MVVM模式了。
对于数据双向绑定不利于代码重用确实是一个问题。基本上重用的代码model都不相同。你可以对这两个model抽象成一个组合model.也可以观察你这个View需要哪些必须的数据,把它当变成成员变量,让他不绑定model.若这个View在两个模块使用,并且发送请求,那么你可以给这个View抽象为一个新的View-Model.
若真像《被神化的MVVM》那篇文章说的那样改进MVC设计模式,那么它就不是 MVC了,它更像不采用ReactiveCocoa的 MVVM了。
【长篇高能】ReactiveCocoa 和 MVVM 入门这篇文章给我们影响最深刻的是ReactiveCocoa的一切皆信号。其实也就是封装了一层block,没有什么神秘的,不过使用起来确实方便,值得推荐,若你会使用原来的老方式也没有什么掉价,并不是你不是你不使用ReactiveCocoa就不是 MVVM.它说了半天完了半天文字动画也没有说明 MVVM的本质,它的本质其实就抽像出来http请求类,增强View的功能,让它像控制器一样发送请求和刷新UI,甚至跳转页面。但是它说出了MVC向MVVM进化的根本方向:对控制器瘦身,增强View的功能,数据双向绑定。但是最关键是只说了优点,没有说它的缺点。兼听则明,偏信者暗。
我相信MVVM比MVC设计模式更先进,值得推荐,ReactiveCocoa 有助于MVVM的使用,它的另一个优点,更有助于模块化。并非文章说为了实现一切皆信号的境界。
既然ReactiveCocoa能有现成的实现MVVM设计模式的方案,而且便于实现软件模块化。那么没有必要必要盲目的反对,可以欣然接受,但是还没有达到盲目非使用不的地步。使用该设计方案,就要用到pods,不然很麻烦,我没有试过替代方案。
我们应该跳出方法论的怪圈,致力那种方案能使我们的软件更容易理解,更容易模块化就用那种方案。使用ReactiveCocoa会引入它的框架,需要使用pods。你不会可能感觉到心理上抗拒采用该技术,一旦你引入了该框架,学会了该技术,它会一劳永远给你以后的开发带来很多方便。


标签:控制器,MVVM,视图,优点,缺点,Model,页面,View
From: https://blog.51cto.com/u_15755990/5982780

相关文章

  • 【24期】请你谈谈单例模式的优缺点,注意事项,使用场景
    单例模式介绍:单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对......
  • 安防监控系统中,工业PoE交换机供电有哪些优点?
    ​   POE(PowerOverEthernet)指的是在现有的以太网Cat.5布线基础架构不作任何改动的情况下,在为一些基于IP的终端(如IP电话机、无线局域网接入点AP、网络摄像机等)传输......
  • 基于微服务的解决方案的缺点
      基于微服务的解决方案有一些缺点: 分布式应用程序分布式应用程序增加了开发者在设计和生成服务时的难度。例如,开发者必须使用HTTP或AMPQ等协议实现服务间通......
  • 工业级交换机的5个常见的优点解析
     随着科技的不断发展,越来越多的工业级交换机逐渐取代了普通交换机。是因为工业级交换机有着普通交换机没有的优势。下面飞畅科技就来为大家详细说说工业级交换机最常见的5......
  • Vue技术5.Vue中的MVVM
    <!DOCTYPEhtml><html><head><matacharset="UTF-8"/><title>理解MVVM</title><!--引入Vue--><scripttype="text/javascript"src......
  • 线程同步的优缺点
    【1】对比:线程安全效率低线程不安全,效率高【2】可能造成死锁死锁》不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死......
  • 不同存储资源的应用场景及优缺点介绍
    容器应用应当根据应用系统的特点,综合考虑容器应用对存储类型、存储性能及数据高可用等方面的要求,选择最适合的存储资源类型。常见的存储资源应用场景包括三类:将存储挂载在外......
  • 不同存储资源的应用场景及优缺点介绍
    容器应用应当根据应用系统的特点,综合考虑容器应用对存储类型、存储性能及数据高可用等方面的要求,选择最适合的存储资源类型。常见的存储资源应用场景包括三类:将存储挂载在......
  • 静态WEB几项缺点
    1、Web页面中的内容无法动态更新,所有的用户每时每刻看见的内容和最终效果都是一样的。为了可以让静态的WEB的显示更加好看,可以加入了JavaScript以完成一些页面上的显......
  • 解决MVVMLight导航VM不重置问题
    问题阐述:使用MVVMLight导航发现导航后VM里面的数据并未进行重置,需要界面跳转后,历史VM也进行销毁重置,并释放解决办法:方法一:在当前界面进行Unloaded进行VM注销并进行重新注......