Android 源码架构模式——MVC、MVP 和 MVVM

本文为 《Android 源码设计模式解析与实战 第二版》 第 25 章到第 27 章的学习笔记,也就是 MVC,MVP,MVVM 三种应用架构模式的笔记。

MVC

mvc 架构是 1978 年由 Trygve Reenskaug 在 Smalltalk-80 系统上首次提出。MVC 的提出是针对一个程序的架构,并不局限于 Android,例如 Spring Boot 里就有通过 MVC 架构实现的写法。

MVC 的本质是分层解耦,将表示层与表示逻辑层分离。

Model:可以是一个独立的对象,也可以是一系列对象的集合。

View:Model 中一些重要数据在视觉上的体现。

Controller:用于连接 User 和 System,党 Controller 接收到用户输出时,会将其转换成合适的时间消息,并将消息传递给一个或多个 View。

MVC 后来的发展多元化,出现了许多分支:

典型 MVC

与 MVC 的通用定义类似:

Model:保持程序的数据状态,与 View 存在一定耦合,即 View 可以通过 Model 查询数据更新视图。同时 Model 还负责接受 Controller 的事件来刷新数据

View:一般由 GUI 组件组成,同时响应用户的交互触发 Controller 的逻辑。同时还可以查询更改 Model 中的数据

Controller:响应 来自 View 的交互请求,然后修改 Model 中的响应数据

image20220220111750862.png

ApplicationModel 型 MVC

在典型 MVC 中,因为 Model 可以使一系列对象的组合,因此 View 和 Model,Controller 和 Model 直接拥有复杂的依赖关系,为了改善这种关系,引入了一个 Application Model。

image20220220112059426.png

以上架构提出的背景环境中,GUI 框架还不够成熟,基本上连用户的交互事件都需要自己实现,此时 Controller 就充当响应交互事件的职责,但随着技术的发展,越来越多的 GUI 框架开始投入使用,而框架中本身就集成了事件响应的功能。例如 Android 中的 View 可以直接设置 Listener 来响应交互。此时 Controller 的地位就比较尴尬。

直到 Web 互联网的出现,MVC 才真正开始流行 ,并提出了 Model 2(实际上就是 Model 不再和 View 耦合)型 MVC

Model 2 型 MVC

image20220220112554908.png

因为 HTTP 的 Web 使用的是请求响应模式,因此 Model 不需要主动通知 View。用户把交互事件发送给 Controller,然后 Controller 完成对 Model 的操作,Controller 再根据操作结果更新 View。同时 Java 也使用一套完整的系统 JavaBean、JSP、Servlet 分别对应 MVC 的三个部分。

Android 作为一个 有完整 GUI 框架的体系,大部分 Android 开发者对 MVC 的认知都是从 Model2 型开始,因此在看到经典架构时会有以下两个问题:

  1. View 层和 Model 层不应该存在耦合
  2. 用户交互事件的响应应该是交给 View 层,此时 Controller 的存在地位就显得尴尬

实际上,第一个问题在 Model2 型中已经得到解决,接下来我们来解决第二个问题。( Model2型并没有解决问题 2,只是因为 Web 的请求响应模型不存在问题 2 )

Model2 改进型 MVC

image20220220113508092.png

实际上很简单就是将 Model2 型中 Controller 中与用户交互有关的逻辑放到 View 层,其他原本的 Controller 逻辑作为新的 Controller 层

至此,绝大多数安卓开发者在学习其他架构之前,使用的都是这种 Model2 改进型 MVC 架构。将 四大组件 作为 Controller,而将 View 体系作为 View 层,同时抽象出 Model 。这种模式在安卓开发中存在一定问题,就是 Controller 的职责模糊,所有逻辑都交给 Controller 实现,导致 Controller 日益臃肿。

架构本就是抽象的东西,一样架构在提出到落地的时候会经过许多改变,最终形成一个具体的某软件中正在使用的架构。MVC 历史悠久,其在多个领域已经有多种分支,具体到项目又有不同的实现体现,因此在学习架构时千万不可以偏概全,例如给应用下定义,贴标签(例如直接认为 MVC 中 Controller 就一定是 Activity,或者将 Activity 认为是 View,这两种思想都可以在某个具体的架构中实现,具体看你整个系统的设计)。学习架构的本质是提高代码的可维护性,可读性,鲁棒性。只要达到要求,就是好的架构。

MVP

MVP 是 MVC 的一个演化版本。

不同于 MVC 讨论的是软件程序,这里讨论的 MVP 是特指 Android 开发中的 MVP 模式,这个模式在其他环境可能有其他的语义,这里不做讨论。

image20220220155510587.png

Presenter:主要作为沟通View 和 Model 的桥梁 ,从 Model 中检索数据后,返回给 View 层。

View:通常指 Actrivity、Fragment 或某个 View 控件。

Model:数据仓库,可以是封装了数据库操作的 DAO,或者封装了网络获取操作的角色。

优点:易于维护、易于测试、松耦合、复用性高

缺点:Presenter 持有 Actifvity 等对象的强引用,在等 Model 回调时,Model 会通过匿名内部类(回调)持有 Presenter,进而持有 Activity。可能会引发一段时间的内存泄漏。

内存泄漏问题可以通过弱引用,和生命周期监听取消回调解决。

MVVM

MVVM 是 MVC 的一种变种把。主要就是 ViewModel 中有一个 Binder ,将 Model 里的数据与 View 中的界面的绑定在一起,称为双向数据绑定(命令式向声明式过渡的产物)

Model:与 MVC 和 MVP 中的 Model 没多大区别,一样是 数据处理的集合。

View:与 MVC 和 MVP 中的 View 没多大区别,一样是处理界面数据

ViewModel:比较模糊,个人的感觉就是提供 Model 与 View 的绑定相关逻辑,也就是 Binding,同时负责数据收集,用户交互事件处理等