架构模式的理解
架构为了解决特定的问题而提出,按照特定的原则将系统整体进行模块/组件/角色的划分,建立模块/组件/角色间的沟通机制。
具体解释一下,首先是要有特定的问题,没有问题空谈架构,仿佛是空中楼阁,没有实用价值,而对应到不同的问题,会有不同的解决方式。
其次是模块的划分要根据特定的原则,没有原则随意划分,也就无从去评估一个架构的好坏。最后就是模块间的通信机制,让系统成为一个整体。
最后,架构模式,其实更多的是一种思想,一种规则,往往一种架构模式可能会有不同的实现方式,而实现方式之间,只有合适与否,并没有对错之分。
单个文件打天下
在早期的Android应用开发中,由于刚开始的业务逻辑还比较简单,为了快速开发,并没有在项目初期就决定采用什么架构模式,一个明显的特点就是处理逻辑都集中在了 Activity / Fragment 中,不管是对 View 的操作,还是对数据的处理。带来的问题就是 Activity / Fragment 中逻辑臃肿,后续扩展牵一发而动全身。而且职责划分不清晰,给后续维护也带来了困难。慢慢的根据前辈的经验积累演化出了MVC、MVP、MVVM等编码模式。
MVC
MVC 架构里,将逻辑,数据,界面的处理划分为三个部分,模型(Model)-视图(View)-控制器(Controller)。各个部分的功能如下:
- Model 模型,负责数据以及对数据的操作。
- View 视图,负责界面的展示。
- Controller 控制器,负责逻辑控制。
MVC 就要解决的问题就是:控制逻辑,数据处理逻辑和界面交互耦合。
在MVC中通信方式是这样的:在 MVC 架构中,View 产生事件,通知到 Controller,Controller 中进行一系列逻辑处理,之后通知给 Model 去更新数据,Model 更新数据后,再将数据结构通知给 View 去更新界面,这就是一个完整 MVC 的数据流向。
优点
结构清晰,职责划分清晰;降低耦合;有利于组件重用
缺点:
其实在 Android 开发中,一般来说,Activity / Fragment 会承担 View 和 Controller 两个角色,就会导致 Activity / Fragment 中代码较多,Model 直接操作 View,View 的修改会导致 Controller 和 Model 都进行改动,增加了代码结构的复杂性。
MVP
MVP 架构里,将逻辑,数据,界面的处理划分为三个部分,模型(Model)-视图(View)-控制器(Presenter)。各个部分的功能如下:
- Model 模型,负责数据的加载和存储。
- View 视图,负责界面的展示。
- Presenter 控制器,负责逻辑控制。
MVP 要解决的问题和 MVC 大同小异:控制逻辑,数据处理逻辑和界面交互耦合,同时能将 MVC 中的 View 和 Model 解耦。MVP 和 MVC 最大的不同,就是 View 和 Model 不相互持有,都通过 Presenter 做中转。
在MVP中通信方式是这样的:View 产生事件,通知给 Presenter,Presenter 中进行逻辑处理后,通知 Model 更新数据,Model 更新数据后,通知数据结构给 Presenter,Presenter 再通知 View 更新界面。
这就是一个完整 MVP 的数据流向。
优点
结构清晰,职责划分清晰;模块间充分解耦;有利于组件的重用
缺点
会引入大量的接口,导致项目文件数量激增;增大代码结构复杂性
MVVM
MVVM 架构里,将逻辑,数据,界面的处理划分为三个部分,模型(Model)-视图(View)-逻辑(ViewModel)。各个部分的功能如下:
- Model 模型,负责数据的加载和存储。
- View 视图,负责界面的展示。
- ViewModel 控制器,负责逻辑控制。
MVVM 要解决的问题和 MVC,MVP 大同小异:控制逻辑,数据处理逻辑和界面交互耦合,并且同时能将 MVC 中的 View 和 Model 解耦,还可以把 MVP 中 Presenter 和 View 也解耦。
我们可以看到,MVP 中的各个角色划分,和 MVC,MVP 基本上相似,区别也是在于角色的通信上。
我们上面说到,在 MVP 中,就是 View 和 Model 不相互持有,都通过 Presenter 做中转。这样可以使 View 和 Model 解耦。
而在 MVVM 中,解耦做的更彻底,ViewModel 也不会持有 View。其中 ViewModel 中的改动,会自动反馈给 View 进行界面更新,而 View 中的事件,也会自动反馈给 ViewModel。要达到这个效果,当然要使用一些工具辅助,比较常用的就是 databinding
。
在 MVVM 中数据的流向是这样的:View 产生事件,自动通知给 ViewMode,ViewModel 中进行逻辑处理后,通知 Model 更新数据,Model 更新数据后,通知数据结构给 ViewModel,ViewModel 自动通知 View 更新界面。这就是一个完整 MVVM 的数据流向。
优点
结构清晰,职责划分清晰;模块间充分解耦;在 MVP 的基础上,MVVM 把 View 和 ViewModel 也进行了解耦
缺点
Debug 困难,由于 View 和 ViewModel 解耦,导致 Debug 时难以一眼看出 View 的事件传递;代码复杂性增大
总结
上面的文章中,我们介绍了 MVC,MVP,MVVM 三种架构模式,以及其简单的实现。这里我们再回过头思考一下,什么时候该使用架构模式呢?
架构模式可以使代码模块清晰,职责分工明确,容易扩展,带来的副作用就是会引入大量的接口,导致代码文件数量激增。
我们在最开始说过,架构模式是用来解决特定的问题的,如果特定的问题在目前阶段不是问题,或者不是主要问题,那么我们可以先不考虑使用架构模式。比如一个功能非常简单,代码量少,而后续又没有扩展的需求,那我们直接使用传统方式进行开发,快速且清晰,完全没有必要为了架构而架构。对于在开始没有考虑架构模式的代码,后续慢慢去重构,也是一个好的选择。