1. 为什么会有 MVP 架构?
1.1 MVC
在此,我先介绍下,MVC架构,毕竟MVP也是从MVC演化过来的
MVC:
View对应于布局文件,其实能做的事情特别少,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,造成了Activity既像View又像Controller
1.2 MVP
Presenter的出现,将Actvity视为View层,Presenter负责完成View层与Model层的交互
- View 对应于Activity,负责View的绘制以及与用户交互
- Model 依然是业务逻辑和实体模型
- Presenter 负责完成View于Model间的交互
MVP View 与 Prestener ,Prestener 与 Model 都是通过接口来通讯
1.3 MVC 与 MVP 的区别
其实最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。
还有一点就是Presenter与View之间的交互是通过接口的(代码中会体现)
2.何用MVP搭建项目架构
2.1 model层
数据模型层,网络请求层,主要包括访问网络,读写服务端的客户类、读写本地数据、SD卡、首选项、ContentProvider等
2.1.1 Utils包:通用的数据访问类所在的包
2.1.2 net包:网络客户端类所在包
2.2 Presenter层
2.3 View层
Activity、Fragment、Adapter、自定义控件,还有暴露给Presenter层的接口都定义在iview包中
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的原理图
10. 什么场景使用MVP?什么场景使用MVC?
若业务逻辑简单的时候,使用MVC架构
若业务逻辑复杂,则需要将业务逻辑从Activity中拆分出来,专门用Presenter层来处理业务逻辑。
Activity、Fragment等处理UI的显示。例如:支付、购物车、收藏、复杂的注册
11. MVP的缺点
每个Activity、甚至每个Fragment都对应着一个IPresenter接口和一个Presenter实现类。
随着Activity和Fragment的增加,Presenter层对应的接口和实现类会爆炸式地增长。
没有业务逻辑的Presenter类实际上只起到modle和view之间的桥梁,没有作用,这称为过度设计。
解决办法:用泛型实现通用的接口来解决