1. 为什么会有 MVP 架构?

1.1 MVC

在此,我先介绍下,MVC架构,毕竟MVP也是从MVC演化过来的
MVC:

View:对应于布局文件
Model:实体模型层,也叫网络请求层
Controllor:对应于Activity

View对应于布局文件,其实能做的事情特别少,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,造成了Activity既像View又像Controller

Android MVP架构解析_业务逻辑

1.2 MVP

Presenter的出现,将Actvity视为View层,Presenter负责完成View层与Model层的交互

  • View 对应于Activity,负责View的绘制以及与用户交互
  • Model 依然是业务逻辑和实体模型
  • Presenter 负责完成View于Model间的交互

MVP View 与 Prestener ,Prestener 与 Model 都是通过接口来通讯

Android MVP架构解析_业务逻辑_02

1.3 MVC 与 MVP 的区别

Android MVP架构解析_业务逻辑_03

其实最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成

还有一点就是Presenter与View之间的交互是通过接口的(代码中会体现)

2.何用MVP搭建项目架构

Android MVP架构解析_业务逻辑_04

2.1 model层

数据模型层,网络请求层,主要包括访问网络,读写服务端的客户类、读写本地数据、SD卡、首选项、ContentProvider等

2.1.1 Utils包:通用的数据访问类所在的包

Android MVP架构解析_业务逻辑_05

2.1.2 net包:网络客户端类所在包

Android MVP架构解析_mvc_06

2.2 Presenter层

Android MVP架构解析_mvc_07

2.3 View层

Activity、Fragment、Adapter、自定义控件,还有暴露给Presenter层的接口都定义在iview包中

Android MVP架构解析_数据_08

3. MVP架构各层之间如何通信?

  • Model层通过接口IModel暴露数据模型层的方法,为Presenter层提供数据
  • Presenter层通过接口IPresenter暴露业务层的方法,为View层提供展示的数据
  • View层通过接口IView暴露显示数据的方法,供Presenter层调用展示数据

3.1 why 通过接口实现各层通信

问什么非要通过接口来实现各层之间的通信?直接调用实现类中的方法不是更直接、便捷吗?

接口限制了调用方能访问的方法。(接口的实现类中)可能有许多方法不想让调用方访问,好处是可以“任性地”添加、删减、修改方法,而不用担心调用方受到影响。一句话就是避免增加耦合

方便团队协作开发
接口定义好之后,如果项目较大,各层可以由不同的人来完成。
写接口实现类的程序员不用担心代码的编写、修改会对调用方的影响。
双方只有在接口暴露的方法上才耦合,其它地方都是解耦的。

3.2 Model层为什么不能绕过Presenter层直接为View层提供数据?

有些情况下,没有什么业务逻辑,得到的数据直接能在View中展示,从技术上讲是成立的。但有业务逻辑时,肯定不行。

即使没有业务逻辑,从不破坏MVP架构来讲,也不能这么做,还容易养成不规范的行为。

4. MVP中的V与MVC中的V相同吗?

MVP中的 V+P 相当于 MVC 中的 C

MVC中的V主要是指layout、menu等res文件夹中显示数据的资源

MVP中的V在形式上与MVC中的C相同,如都是包含Activity、Fragment、Adapter等

但MVP中的Activity、Fragment、Adapter等将业务逻辑剥离出来,放到了P层。剩下的就是将数据展示在layout、menu等处的代码

5. MVP 相对MVC的优势是什么?

  • 解耦,耦合度低,修改某层的代码,不影响或极少影响其它两层。方便项目的维护
  • 复用性高:由于M和P中没有展示数据的代码,因此与Activity、Fragment、Adapter甚至是自定控件都完全解耦。可以复用到其它的View
  • Model可以复用到其它的Presenter

6. MVP 架构中能否创建一个Model、一个Presenter和一个IView用来对应多个Activity、Fragment?

技术上可以实现,但View层的接口不要用一个,否则凡是实现IView接口的Activity、Fragment等都要实现所有抽象方法,造成大量冗余的空方法

用一个Model、一个Presenter也不可取,因为Activity、Fragment等在调用IPresenter中暴露的方法时,却能看见其它Activity、Fragment中需要的方法。这也违反了定义接口的初衷,所以这种做法不可取。开发中千万不要这么做!

9. 画出MVP的原理图

Android MVP架构解析_业务逻辑_09

10. 什么场景使用MVP?什么场景使用MVC?

若业务逻辑简单的时候,使用MVC架构

若业务逻辑复杂,则需要将业务逻辑从Activity中拆分出来,专门用Presenter层来处理业务逻辑

Activity、Fragment等处理UI的显示。例如:支付、购物车、收藏、复杂的注册

11. MVP的缺点

每个Activity、甚至每个Fragment都对应着一个IPresenter接口和一个Presenter实现类。

随着Activity和Fragment的增加,Presenter层对应的接口和实现类会爆炸式地增长。

没有业务逻辑的Presenter类实际上只起到modle和view之间的桥梁,没有作用,这称为过度设计。

解决办法:用泛型实现通用的接口来解决