1.MVP架构
所有app都需要一个清晰的软件架构,否则很容易创建无所不知、无所不能的上帝类。上帝类的维护成本很高,并且难以测试和扩展。
如果一个类需要花费时间从其他类中通过get()和set()检索数据,也就是说需要深入业务并且告诉它们如何去做,那么就应该把这些功能函数更好的组织到其它类中,而不是在上帝类中。
由于Android中允许View和其它线程共存于Activity内,此时如果不考虑架构的话,Activity类就会越来越大。这样最大的问题就是在Activity中同时存在业务逻辑和UI逻辑,造成Activity的臃肿,也会增加测试和维护的成本。
MVP是Android中常用的架构,MVP代表Model、View和Presenter。其中,View层负责处理用户事件和视图部分的展示,它可能是Activity或者Fragment类;Model层负责访问数据,数据可以是远端的Server API、本地数据库或者SharedPreferences等;Presenter层是连接(或适配)View和Model的桥梁。
view只是负责处理事件监听或展示每个视图组件,它涉及到的所有业务逻辑必须委托给Presenter类。在MVP中,View和Presenter是一 一对应的(在MVVM中是一对多的)
可见,View从不直接与Model通信。
MVP模式实现了显示层和逻辑层的分离,即功能接口如何工作与功能的展示是分离的,MVP模式理想化地可以实现同一份逻辑代码搭配不同的显示界面。
注意,高层接口(view层)不知道底层接口(Model层)的细节,更准确地说高层接口不能,不应该,并且必须不了解底层接口的细节,是面向抽象的,并且是细节隐藏的。
MVP架构的优缺点:
①优点
耦合降低,Presenter变为纯Java的代码逻辑, 不再与Android Framework中的类如Activity、Fragment等关联, 便于写单元测试。
MVP很好的体现了单一职责的原则,并且严格分为三层,即使后期业务变多,结构仍然清晰,非常利于项目后期的维护。当有新的需求时,只需将相关的需求写在接口,然后实现这个接口,无需顾及之前的结构,免去几方面去调整的头痛。另外,还能更好的对接口代码进行单元测试。
②缺点
1)使用MVP模式构建项目,会造成类文件和接口文件过多,进而增大包的体积。
官方提供的解决办法是写一个Contract接口,把与MVP三层的相关接口全部列入到里面去:
public interface Contract {
public interface IModel {
xxx;
xxx;
}
public interface IPresenter {
xxx;
xxx;
}
public interface IView {
xxx;
xxx;
}
}
2)可能存在内存泄漏的问题。
比如用户关闭了View层,但此时Model层如果仍然在进行耗时操作,因为Presenter层也持有View层的引用,所以造成垃圾回收器无法对View层进行回收,这样就造成了内存泄漏。
解决办法是重写onDestroy()方法,在View销毁时强制回收掉Presenter。
还有一个解决办法就是采用弱引用的方式:
WeakReference< xxx> refrence = new WeakRefrence<>(this);
// 使用时直接就能获得对象的引用
reference.get();
然后在引用进行引用之前,都需要判断引用不为空,以防止空指针异常。
2.MVP与MVC比较
MVP其实是从MVC模式演化产生的,先看一下著名的MVC模式:
View:对应于布局文件
Model:业务逻辑和实体模型
Controller:控制器,Android中对应于Activity
对应的MVC交互图:
仔细看一下View层和Activity,具体view布局文件中的数据绑定和事件处理的方法代码都是冗余在Activity中的,所以经常可以看到Activity类动不动就是少则九百行,多则上千甚至几千行。
现在对比看一下MVP模式,MVP模式引入了 Presenter层,用来完成View层和Model层的交互,具体MVP对应如下:
View层:View通常是由Activity实现的