谈 MVP 之前我们先来聊一聊软件开发中的模式,在软件开发中由于需求的不断变更,产品的不断迭代,程序员们为了应付产品经理不断变化的需求,提出了一系列的定式。定式一词最早应该是来源于围棋中的术语,围棋的定式本质上也就是通过一定开局方式来提高围棋的胜率,软件开发中也是一样的,通过精心设计的一系列定式,来解决软件开发中反复遇到的一些问题,来快速响应产品需求。
关于 "模式" 在开发中会会提及两个词,设计模式和架构模式,两者是有区别的,我的理解是:设计模式更加关注于微观,架构模式更加关注于宏观设计。往往都是架构模式针对的是整个产品层面的设计,设计模式针对的是产品中的某一个功能点的设计,比较常见的 MVC 和 MVP 就属于宏观架构模式,观察者和模板模式就属于微观设计模式。当然也不是绝对的,设计模式中也可能具有宏观架构,架构模式中也可能有微观架构,不过从并集结构来看,大体如此。
架构模式的设计更加注重于产品业务层面的考虑,常见的框架模式有如下几种:
当然,在实际设计中可能会有多种框架设计方式结合一起。关于设计模式和架构模式,推荐两本书,GOF 的《设计模式》和 Frank Buschmann 的《面向模式的软件设计》。
MVC 模式本质上就是属于框架模式中的分层架构,分层架构其实就是模仿自然界各司其职的思维方式,这种思维在互联网公司的组织架构中尤其明显,产品经理负责功能规划,软件开发工程师负责开发出对应功能,测试人员保证软件质量。网络协议也是一个著名的分层思想 :
Java EE 是一个天然的 MVC 分层架构
MVC 优缺点网上有很多人谈,比如 MVC 具有低耦合性,高内聚性、可维护性强等等,缺点是需要新建的类非常多,C 层快速膨胀等等。但是这些都不是致命的缺点,真正致命的缺点后面再谈。
下图直观的显示了 MVP 和 MVC 的区别:
几句话来区分一下 MVP 和 MVC:
MVP 和 MVC 比有什么好处?一句话来说:
明显,P 层就是 MVP 种的中心节点,中心节点有什么好处?
所有的数据都从 P 层流入,流出,数据流向透明、可控,MVC 具有的一优点 MVP 都有,而 MVC 由于缺少中心化的数据控制层,所以 V 层可以直接和 M 层通信,导致数据的流入和流出一团糟,这个就是 MVC 的致命缺点之一,它本身违背了分层思想中的分层隔离的思想。
Android 开发中为什么 MVC 不好使,一个原因是 Android 本身就不是一个天然的 MVC 架构,它只是一个类 MVC 架构,M 层是数据层,C 层是 Activity/fragment,V 是 XML 文件,XML 的生命周期又需要依赖于 Activity/fragment,所以在 Activity/fragment 中会有对 View 的操作。 另外一个原因是 MVC 在 Android 开发中的局限,V 层会经常对 M 层做通信,比如 V 层中接收 M 层数据的变化, 刷新页面, 这种直接 M 直接作用于 V;有时候可能 C 层也会直接通知 V 层来响应数据的变化, 如果出现 BUG, 你很难找到是哪一个部分导致的. 而 MVP 模式通过把逻辑缩到 P 层,通过在 View 和 presenter 之间增加一层接口, 而减少 model 和 view 层的交互, 从而把部分逻辑完全转接给 presenter 层, 进一步减少了 View 层的逻辑, 这样依赖 View 能够真正的做到完全处理 UI 方面的工作.
优点说完了,缺点也同样明显。MVP 的中中心化的问题在于中心节点承载过多的逻辑,导致 P 层不断臃肿,特别是在 Android 开发中,网络请求、数据库操作、控制逻辑等等,P 层逻辑不断增加,最后出现了一个巨型的上帝类。
这个时候你需要一个工具,去简化 P 层代码。
RxJava 正是这个工具。RxJava 是什么,简单来说:
RxJava 让你通过事件流的方式来对数据进行操作,这种操作包括数据的组合、包装、监听,并且让你在同步和异步线程中自如切换。
关于 RxJava 更多介绍, 点击这里
RxJava 在 MVP 中起到的作用:
通过对事件流的操作,减化 P 层的逻辑,减少代码的耦合
怎么减少?
一句话来说:
更多关于 RxJava 的学习参考其它教程。
MVP 的实践基本是基于谷歌 官方的架构
具体工程实践下一篇在讲。
软件架构永远是服务于业务的,业务的复杂度决定了架构的简洁性,在很多时候,架构不是万能的,在无法用架构解决情况下,考虑对业务做精简和分层能够达到很好的效果。MVC 架构在分层架构中是占有非常重要的地位,不过由于 MVC 本身的缺点和 Android 自身架构的局限性,原生的 MVC 在 Android 应用会有非常多的问题,而 MVP 架构的分层 + 中心化的架构模式能够在 Android 的项目中取得良好的效果。
来源: https://juejin.im/post/5a37957a5188257d6929b1e3