一.MVC
- 目标:解决了应用程序中业务逻辑、数据和界面显示的耦合问题
- 三个核心组件:模型(Model)、视图(View)和控制器(Controller)
模型(Model):负责数据和数据业务逻辑,通常包含数据存储、检索和业务规则(视图元素的互动逻辑放到控制器里,这里只有简单的数据业务逻辑)。
视图(View):负责使用模型的数据显示用户界面,不包含业务逻辑(没有数据逻辑,没有界面元素的互动逻辑,这里只是简单的拿数值来改变界面样式的展示逻辑)。
控制器(Controller):接收用户的输入,调用模型和视图去完成用户的请求(视图元素的互动逻辑放这里,因为大量的逻辑会放到控制器,所以控制器是三个MVC组件中最复杂的一个)。 - 持有关系:
视图持有模型对象
模型不持有任何对象
控制器持有模型和视图对象 - 交互逻辑:
1.用户在界面点击 -> 控制器通过持有模型修改的数据 -> 控制器通过持有的视图更新界面 (从逻辑可以看出界面会持有控制器对象)
2.用户在界面点击 -> 通知控制器通过持有模型修改的数据 -> 通知视图更新界面 (从逻辑可以看出界面会可以不持有控制器对象,这样控制器对象可以放在别的地方) - 实际应用关系:
1.界面绑定视图对象,界面持有控制器对象,控制器持有模型对象和视图对象(也有另一种方式:界面绑定视图对象和绑定模型对象,界面持有控制器对象,控制器持有模型对象和视图对象)
2.界面绑定视图对象,控制器持有模型对象和视图对象(这种是以广播的方式驱动控制器和视图) - 优点:
降低用户界面与业务逻辑之间的耦合性 - 缺点:
不适合中小规模的软件项目
二.MVP
- 目标:解决了应用程序中业务逻辑、数据和界面显示的耦合问题,在MVP架构中,P占据主导地位,充当Model和View的桥梁,实现View和Model两者之间的隔离。
- 三个核心组件:模型(Model)、视图(View)和表示器(Presenter)
模型(Model):负责数据和数据业务逻辑,通常包含数据存储、检索和业务规则(视图元素的互动逻辑放到表示器里,这里只有简单的数据业务逻辑)。
视图(View):负责使用模型的数据来显示用户界面,不包含业务逻辑(没有数据逻辑,没有界面元素的互动逻辑,这里只是简单的拿数值来改变界面样式的展示逻辑)。
表示器(Presenter):接收用户的输入,调用模型和视图去完成用户的请求(视图元素的互动逻辑放这里,因为大量的逻辑会放到控制器,所以控制器是三个MVP组件中最复杂的一个)。 - 持有关系:
视图不持有任何对象
模型不持有任何对象
表示器持有模型和视图对象(也有另一种表示器只持有模型,视图和表示器通过广播来通信) - 交互逻辑:
用户在界面点击 -> 通知表示器,表示器通过持有的模型对象修改数据 ->模型修改完后->通知表示器修改完数据 -> 表示器通知(或直接调用)视图更新界面 - 实际应用关系:
界面绑定视图对象,表示器持有模型对象和视图对象(模型和视图都要经过中间的表示器来通信) - 优点:
解耦,视图和模型完全分离,所有交互都在P中实现,M的设计可以更加灵活,有利于M的高效使用。 - 缺点:
Presente层与View层是通过接口进行交互的,交互会过于频繁,接口粒度不好控制,粒度太小,就会存在大量接口的情况,使代码太过碎版化;粒度太大,解耦效果不好。
View层与Presenter层还是有一定的耦合度,一旦视图变更了,presenter也要变更。
三.MVVM
-
目标:达到更加清晰的结构和高效的开发效率,它是由MVC的演变而来,在MVC的基础上更进一步细化界面元素和数据的绑定粒度(mvc是以整个界面为单位,而MVVM以界面的某个控件为单位)。
-
三个核心组件:模型(Model)、视图(View)和视图模型(ViewModel)
模型(Model):负责处理数据和业务逻辑。它可以是从网络获取的数据、数据库中的数据或其他数据源。Model层通常是独立于界面的,可以在多个界面之间共享。
视图(View):负责展示数据和与用户进行交互。它可以是Activity、Fragment、View等。View层主要负责UI的展示和用户输入的响应。
视图模型(ViewModel):连接View和Model,作为View和Model之间的桥梁。它负责从Model中获取数据,并将数据转换为View层可以直接使用的形式。ViewModel还负责监听Model的数据变化,并通知View进行更新。ViewModel通常是与View一一对应的,每个View都有一个对应的ViewModel。 -
持有关系:
视图通过事件或回调间接持有视图模型(通过继承特定的类,这个特定类主要功能就是视图有交互时通过特别的标识去找相应的视图模型进行回调或发送事件)
模型通过事件或回调间接持有视图模型(通过继承特定的类,这个特定类主要功能就是模型有数据变化时通过特别的标识去找相应的视图模型进行回调或发送事件)
视图模型持有模型细分单元和视图对象细分单元(也就是把大部件拆分成小部件提升可重用度) -
交互逻辑:
用户在界面点击 -> 间接执行视图模型的方法,视图模型通过持有的模型细分单元修改数据 ->模型细分单元修改完后->间接执行视图模型的方法 ,视图模型通过持有的视图细分单更新界面 -
实际应用关系:
界面绑定视图对象(继承特定的类),视图模型持有模型对象(继承特定的类)和视图对象,模型和视图都要经过中间的视图模型来通信。 -
优点:
解耦更彻底,开发效率更高,产品开发生命周期更短。 -
缺点:
数据绑定会消耗额外内存资源,复杂度更高,学习成本也更高。
四.MVI
-
目标:达到简化流程,降低复杂度,减少学习成本,拒绝Bug(其实本质就是界面和数据两者关系,只要把这两者解耦,以最大程度独立分离)。
-
二个核心组件:视图(View)和视图模型(ViewModel)
视图(View):View层主要负责UI的展示和用户输入的响应。
视图模型(ViewModel):获取数据,并将数据转换为View层可以直接使用的形式。 -
二个共用组件:(这二个组件是所有的视图和视图模型不用修改都能用的组件,一般以代理或回调方式实现,因为代理和回调比广播更好跟踪和更高的性能)
意图(Intent):用于View层给ViewModel传送交互数据
状态(State):用于ViewModel回调View层修改UI -
持有关系:
视图持有意图Intent断开和视图模型(ViewModel)的关联
视图模型持有状态State断开和视图(View)的关联 -
交互逻辑:
用户在界面点击 -> 视图执行意图Intent的方法,意图Intent调用视图模型修改数据 ->视图执行状态Statet的方法,状态Statet调用视图更新界面 -
实际应用关系:
界面绑定视图对象(继承意图Intent类),视图模型单独不持任何对象(继承状态Statet类),闭环关系(视图->意图Intent->视图模型->状态Statet->再回到视图)。 -
优点:
数据单向流动,架构更简单、易于调试。 -
缺点:
由于每个视图都要开一份意图Intent内存,每个视图模型都要开一份状态State内存,会消耗更多的内存资源,对于有内存要求的小应用可能就不是很好。