这里会围绕下面这个基本的架构图从几个关键点进行详细的讲解
MVPH框架的核心思想之一,单向引用。即Presenter单向持有View和Model的引用,View和Model原则上不能持有Presenter的强引用,这是和传统MVP模式的一大区别,因为传统MVP以Activity为View时,通常有需要持有Presenter的强引用,Presenter又同时持有Model和View的强引用。也就是说Presenter和View相互持有对方的强引用,这是非常不好的,相互引用就表示相互依赖,也就意味着耦合大大增加,而单向引用的好处正好可以避免这种问题,Presenter单向持有View和Model时就表示View和Model通常是不需要受Presenter的影响,因为他们自己内部根本不知道自己被谁调用了,这也符合设计原则中的最少知道原则,自己只需要做好自己的事情,而不需过多关注其他人在做的事情。
面向接口编程是一个很早就在提倡的理念,事实证明,面向接口编程也确实比面向具体编程更容易维护和扩展。面向接口也算是MVP的核心思想了,MVP提倡的就是通过接口解耦。MVPH也不例外的大量使用了接口方式来进行一些设计,比如BasePresenter这个基类,BasePresenter使用泛型方式声明了View变量mView,Model变量mModel,实例化当然是具体到每个Presenter的实现类来实例化的,不过MVPH采用的是子类传递泛型声明变量,抽象方法返回实现类类名反射实例化变量,不统一使用泛型传递到基类主要还是为了代码的美观,毕竟在类名上返回4个泛型,看着还是挺头大的。
MVP中因为Activity和Fragment的问题,通常会创建两个BasePresenter基类,但是这样就会造成BaseActivityPresenter和BaseFragmentPresenter中产生重复的方法,毕竟他们都是实现了IBasePresenter接口的,这时MVPH采用的是把这些方法的具体实现交给另外一个通用的Helper类来处理,这么做的好处是,能保证Activity和Framgent中,相同方法,实现也基本相同。
BaseView
BaseView实现了IBaseView接口,内部持有一个BaseViewHelper对象。目前来说不管是activity和fragment,他们View都是继承自BaseView,他们的Model都是继承自BaseModel,只有Presenter有区分不同的基类。
BaseModel
BaseModel实现了IBaseModel接口,内部持有一个BaseModelHelper对象。
BaseActivity(Framgent)Presenter
这里统称为BasePresenter,BasePresenter实现了IBasePresenter接口,内部持有一个BasePresenterHelper对象,并持有使用接口方式声明的View和Model对象,可以直接使用变量mView和mModel调用对应接口中声明的所有方法。
BaseViewHelper,BaseModelHelper,BasePresenterHelper
这三个Helper基类都继承自BaseMvpHelper类,开发者在MVPH架构中自定义Helper类时需要继承BaseHelper类,因为只有BaseHelper的子类才能被以上三个基础Helper进行组合添加。
BaseHelper
BaseHelper类是所有自定义helper的基类。
BaseMvpHelper
BaseMvpHelper类是三个基础helper类的基类,用于扩展更多的Helper类到当前Helper类以增加当前Helper的功能。
IBaseVP
IBaseVP接口为加载参数控制接口,presenter和view同时实现此接口,这么设计是为了同时兼容MVP和MVC两种模式下进行开发。具体配置规则请参考LayoutConfig。
这里采用半实例的方式讲解MVPH的逻辑复用方法,首先上图
图中示例为两个具有部分相同功能逻辑的activity,如图所示,我们现在一共有4个可复用逻辑:
- 图片列表(可以修改图片和上传)
- 时间选择器弹窗(可以选择时间)
- 传统list列表界面功能
- 特殊的输入框逻辑
1和2,两个界面都包含有的功能是选择图片和时间选择器功能,1独有的功能是列表,2独有的功能特殊输入框(这里说的独有是针对这两个界面而言,如果真的只有一个界面有的功能则完全没必要单独封装成helper类)
从示意图已经可以看出,上面4个需要被复用的逻辑都被单独抽离成了对应helper类。这样,每个需要使用其中一个功能的界面,只需要用自己自带的helper进行添加扩展就可以调用需要的逻辑方法。
优点:可以充分分离各种需要复用的功能代码,不会造成强耦合。复用代码统一管理,方便扩展与修改,由于同个功能都是引用的同一个helper类,所有需要修改或扩展时,通常只需要进行少量修改即可。方便进行逻辑复用,由于使用了分离式的逻辑实现,因此任何需要复用的逻辑都可以简单的进行接入和删除。
备注:设计思想虽然是如此的,但是每个人的水平不同,所以封装出的helper类也大不相同,这里说几个封装helper的基本原则:
-
ViewHelper和ModelHelper不应该相互依赖。而PresenterHelper则可以直接引用这两个helper并进行逻辑控制,这点和MVPH的引用原则相同。
-
PresenterHelper可以直接引用IView和IModel,IBasePresenter接口,但是这里的引用应该是引用父类基础接口而不应该引用某个具体activity或fragment的具体接口,因为引用到具体接口明显会造成强耦合,造成复用的局限性。
-
划分粒度的控制。对于helper类粒度的控制非常重要,因为粒度过细会造成使用复杂,维护困难,粒度过粗则会造成因为包含的东西过多而无法复用或者可以复用但是明显的冗余。