一、MVC
MVC的基本结构
MVC(Model-View-Controller)是桌面开发中常见的软件架构。标准的MVC架构图如下:
Model(模型) :负责业务数据管理和处理,包括增删改查。Model必须提供外部可以操作模型数据的接口,同时在数据发生变化后能够通知外部
View(视图) :用户界面。View需要感知Model的变化,数据变化时,更新用户界面
Controller(控制器):业务逻辑层。Controller需要感知View的事件,调用Model提供的接口对数据进行操作
MVC的工作流程
1、用户对界面进行操作,触发View的相关事件;
2、View感知这些事件,通知Controller进行处理;
3、Controller处理相关业务,并通过Model的接口对业务数据进行更新;
4、Model的业务数据改变触发相应事件,通知View业务数据已经发生改变;
5、View捕获到Model发出的数据改变事件,重新获取数据并更新用户界面。
MVC的优缺点
优点:
降低用户界面与业务逻辑之间的耦合性。大大降低了用户界面和业务逻辑的耦合性,可以隔离模块间的变化,有利于维护和扩展。
复用性高。多个视图可以共享一个模型。
MVC可以将一个项目分为三个子项目分别进行开发和管理,有利于软件工程化,也可实现独立部署。
因为业务逻辑和界面的分离,为业务模块的单元测试创造了条件。
缺点:
不适合中小规模的软件项目。MVC引入了更多概念,增加了项目结构和实现的复杂性,将其应用到中小规模项目通常得不偿失。
更多的内存消耗。Model中的内容都可以从界面获取到,因此,Model的引入增加了内存消耗。
降低了程序性能。因为实现的复杂性,势必会导致性能降低。
二、MVP
MVP的基本结构
MVP(Model-View-Presenter)是从MVC演变而来的。在MVC的基础上,MVP强调Model与View之间的隔离,两者互不感知。MVP的架构图如下:
在MVP架构中,P占据主导地位,充当Model和View的桥梁,实现View和Model两者之间的隔离。
MVP的工作流程
1、用户对界面进行操作,触发View的相关事件;
2、View感知这些事件,通知Presenter进行处理;
3、Presenter处理相关业务,并通过Model的接口对业务数据进行更新;
4、Model数据变化会通知Presenter;
5、Presenter收到Model数据变化通知后,调用View暴露的接口更新用户界面。
MVP的优缺点
优点:
解耦,视图和模型完全分离,MVC常常会因为V和M的耦合性太强而渐渐导致C失去控制作用。
所有交互都在P中实现,M的设计可以更加灵活,有利于M的高效使用。
缺点:
Presente层与View层是通过接口进行交互的,交互会过于频繁,接口粒度不好控制,粒度太小,就会存在大量接口的情况,使代码太过碎版化;粒度太大,解耦效果不好。
View层与Presenter层还是有一定的耦合度,一旦视图变更了,presenter也要变更。
复杂的业务同时也会造成接口类爆炸问题。使用MVP模式去构建项目,会造成类文件和接口文件的过多,代码臃肿,进而增大包的体积
简单解决 :写一个Contract接口,然后把与MVP相关接口全部列入到里面去
可能会造成内存泄漏的问题。当用户关闭了View层,但这时Model层如果仍然在进行耗时操作,因为Presenter层也持有View层的引用,所以造成垃圾回收器无法对View层进行回收,这样一来,就造成了内存泄漏。
三、MVVM
MVVM的基本结构
MVVM(Model-View-ViewModel)也是MVC的演变而来。由微软公司提出并在WPF上大量应用。MVVM强调数据绑定,从而省去了模型数据改变后通知数据更新的步骤。MVVM的架构图如下:
Model :业务数据
View :用户界面。用户界面代码编写时,直接将M中的业务数据以声明方式绑定到对应的视图组件上。
ViewModel:核心功能有2个:1)界面渲染完成后,将声明绑定到View上的业务数据和View进行双向绑定,同步更新;2)相应View的事件,操纵M实现业务处理。
MVVM的工作流程
1、界面渲染完毕后,ViewModel会将View和Model按照开发时声明的方式进行双向绑定;
2、用户对界面进行操作,触发View的相关事件;
3、ViewModel感知View发出的事件,调用Model的接口处理业务逻辑;
4、Model内容改变,用户界面立即更新,无需额外操作。
MVVM的优缺点
优点:
解耦更彻底
开发效率高,产品开发生命周期短。通过数据双向绑定,不需要手动更新界面,实现了关注点分离,降低了开发的复杂性和工作量;
双向绑定可以通过感知模型数据的变化提前感知界面即将发生的变化,优化该过程,可以提高界面的渲染速度,避免重复渲染。
缺点:
数据绑定会消耗额外资源,占用更多的内存
数据绑定会导致模型数据的变化变得难以追踪,调试困难
数据双向绑定不利于代码重用。
也有一些MVVM框架采用单向数据绑定+UI事件劫持的方式 ,这里简单介绍下双绑和单绑的区别:
一般只有UI表单控件才存在双向数据绑定,非UI表单控件只有单向数据绑定。
单向数据绑定:M的变化可以自动更新到ViewModel,但ViewModel的变化需要手动更新到M(一般通过给表单控件设置事件监听实现)
双向数据绑定:M的变化可以自动更新到ViewModel,ViewModel的变化也可以自动更新到M
双向绑定=单向绑定+UI事件监听,双向和单向只不过是框架封装程度上的差异,本质上两者是可以相互转换的。
优缺点:
单向数据绑定的优点是数据更易于跟踪管理和维护,缺点是代码量较多比较啰嗦。
双向数据绑定的优点是代码量少、简洁,缺点是数据不易于跟踪管理和维护。
四、MVI
MVI基本结构
模型-视图-意图
出现的目的是为了解决MVVM中双向绑定数据的不足。把双向绑定变成单向数据流。使用Flow代替LiveData存储数据。
Model:这里的Model不是其他框架中的Model层,在MVI框架中表示存储UI的状态。
View:在MVI中View层主要是接口,负责相应UI的状态。
Intent:在MVI中Intent(和Android中的Intent不是同一个)主要负责传递UI状态。使用sealed关键字,形成一个封闭类,类似枚举。主要用于V层通知ViewModel处理数据。
State:和Intent一样是一个封闭类,主要用于ViewModel回调数据修改UI。
MVI特点
唯一可信源:数据只有一个来源(ViewModel),与MVVM思想相同
单向数据流:状态向下流动,事件向上流动。
响应式:ViewState包含页面当前状态和数据,View通过订阅
ViewState就可以完成页面刷新。相比于 MVVM 是新的特性。
优点:
1.UI的所有变化来自State,所以只需聚焦State,架构更简单、易于调试
2.数据单向流动,很容易对状态变化进行跟踪和回溯
3.State实例都是不可变的,确保线程安全
4.UI只是反应State的变化,没有额外逻辑,可以被轻松替换或复用
缺点:
1.所有的操作最终都会转换成State,所以当复杂页面的State容易膨胀
2.State是不变的,每当State需要更新时都要创建新对象替代老对象,这会带来一定内存开销
👀关注公众号:Android老皮!!!欢迎大家来找我探讨交流👀