快速回顾
上一章(Android MVP系列(四)之MVC下篇)我们已经组装了一个完整的MVC架构,我们可以看一下MVC框架的流程图:
当然这张图只是说明了上一章新增的功能:下拉刷新 的流程图。可以看出Module层和View层之间是没有交互,让Controller层去沟通传递数据,这样看起来就和MVP的原理一样,但是这还是有点差异的,什么样的差异我们之后来讲。
另外还有个需求是进入界面初始化列表数据,这个需求是Module层和View层直接沟通,这个和MVC的架构是相符合:Controller层只是负责转调Module去请求数据,而Module层请求完数据之后直接沟通View来获取数据,更新列表。
MVC过度到MVP
上一章场景
由于房东比较忙,他给中介说,我比较忙我不想和租客去沟通价格、修理家具。。。等等很多的事情,你都给我办了,包括租金,租约你都处理了,我就收钱就好了,其他的我不管
租客==View、中介==Presenter、房东==Module
租客(View)只和中介(Presenter)联系,房东(Module)也只和中介联系(Presenter);假如中介换人了,按照之前的结构不需要任何改变,复用性强;现在房东只管收钱就好了,其他的事情都由中介处理,租客交租金、修电器、出现的等等问题,直接和中介沟通解决,等于可扩展性也强。
这个图我相信大家看着应该非常的眼熟了,这个和MVP的图已经完全符合了;
我们MVP中的Presenter的功能和场景中的中介者有着异曲同工之妙,他们的功能都是起到了隔离View(租客)和 Module (房东)的作用。
我们用一个完整的图来显示从MVC演变到MVP:
这里我们假设MVC架构为场景一、MVP架构为场景二;那么场景一和场景二的区别在哪儿呢?
区别:中介功能变化
场景一:中介负责处理流程的控制,功能单一。相当于说租客询问中介你那边有房源么?我需要租个什么样的房子,中介筛选租客需求之后,锁定了一个房东有这样的房源,然后给房东说有人要租你的房子,然后房东和租客去沟通,最终达成合作。
场景二:中介除了负责流程的控制,还起到了隔离租客和房东的作用。这个过程就等于说租客找到中介,我要租房子,价格、环境。。。需求,中介去和房东沟通,房东说可以,中介收取租客租金、签订合同等等,然后中介把钱、合同给房东。
那么将上面的描述转换成MVC和MVP的区别:
MVC中的Controller只起到接收View的控制和转调Module,之后Module请求好数据,直接通知View就好了,View获取数据更新界面
一句话总结:Controller负责流程的控制
MVP中的Presenter的作用是:不仅Presenter要接收View的控制和转调Module请求数据,而且还要监听Module的数据和通知并传送数据到View更新界面。
一句话总结:Presenter控制流程和隔离View、Module
上面就是我们之前提出来的差异。
真正的MVP结构
如果说按照上面所说的,修改下Controller层的功能就过度到MVP的话,大家会不会觉得太容易简单了,事情并不那么简单。如果说改变下Controller层的功能就转变成MVP的整体框架的话,我们把MVP比喻成一个人的话,那么当前我们只是拥有一副骨骼,需要真正的能运动起来我们还需要我们的经络系统,那么什么是我们的经络系统呢?下面我就要提到一个概念:接口化。
相信什么是接口,就不需要解释了吧,下面我将用实例来看看我们的MVC转变MVP。
MVP框架设计
相信看过前面的文章的同学应该知道怎么划分结构,我长话不多说直接开始撸起走了。
场景
场景我就不改变任何东西了,和之前的场景是一模一样的。这样方便同学能够和MVC做个对比,更加深刻的认识MVP。
1.展示新闻列表
2.支持刷新功能
有点小小的区别就是,我们这里就不将数据缓存到内存中,直接获取。
开始撸MVP框架
1.定义Module
/**这是一个Model**/
public class Module{
private PresenterListener presenter;
//构造方法传入presenter
public void Module(PresenterListener presenter){
this.presenter=presenter;
}
//从服务器请求获取新闻列表数据
public List<NewsBean> getNewsData() {
//耗时获取数据
...
//加载完成之后发送事件给观察者 假设返回的数据是datas
presenter.onLoadDataFinish(datas)
}
}
这里可能有人会看到 PresenterListener 是什么?哪里来的,这个就是之前提到的 观察者,待会儿我们让Presenter去实现PresenterListener这个接口。这样就能监听Module获取新闻。
2.定义Presenter
先按照需求提取出方法来,假如是通用的功能就提取出来,可以供很多的界面使用(例如:列表都有获取新闻、使用RecycleView都会有setAdapter()等等通用的功能)
public interface IbasePresenter{
//当前就一个需求请求列表数据
void getNewsList();
//有多个需求的时候,把方法抽取出来即可
...
}
然后定义一个观察者,观察Module数据加载完成
public interface PresenterListener{
//监听Module数据加载完成
void onLoadDataFinish(List<NewsBean> datas);
}
最后Presenter来实现IBasePresenter,PresenterListener:
public class Presenter implements IBasePresenter,PresenterListener{
private IBaseView view;
private Module module;
public void Presenter(IBaseView view){
this.view=view;
module=new Module(this);
}
@Override
public void getNewsList(){
module.getNewsData();
view.showLoading();
}
@Override
public void onLoadDataFinish(List<NewsBean> datas){
view.setData(datas);
view.hideLoading();
}
}
3.定义View
可以从Presenter中可以看到我们需要将Presenter注入
public interface IView {
void setPresenter(Presenter p);
}
抽出一个BaseView实现View
public abstruct class BaseView implements View {
Presenter presenter;
void setPresenter(BasePresenter presenter) {
this.presenter = presenter
}
//刷新数据
abstruct updateView();
}
最后怎么使用呢?
public class MainActivity extends AppCompatActivity implments BaseView{
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Presenter presenter = new Presenter(this);
presenter.getNewsList();
}
@Override
public void updateView(List<NewsBean> datas) {
//do view
}
/**模拟刷新新闻**/
@Override
public void onRefresh(){
presenter.getNewsList();
}
public void showLoading(){
//显示loading界面
}
public void hideLoading(){
//隐藏loading界面
}
}
这样我们可以看下上一篇文章的MVC和MVP对比是不是相似度极高,所以我之前花了几个章节讲MVC的原因,我相信这样你会更加的掌握MVP框架。
至此我们的MVP的框架就搭建完成了,上面的例子都是很简单的,目的是为了帮助大家理解。不知道大家清楚这个MVP的框架搭建流程与否,如果不知道的可以多看两遍或者实际代码敲两遍。还有点需要说明的就是,我们在搭建的时候一定要根据业务来去定义我们的接口,千万不要照着代码敲,而是要理解这个框架的设计思想。
还有一点需要提出来的就是:
Presenter的生命周期的管理,使用不好就容易造成内存泄漏,所以我们要在Presenter中根据View的生命周期来绑定。
总结
现在我们的MVP的框架已经学习完成了,不知道大家的学习的程度怎么样,这几章的学习主要 理论+简单的逻辑 来讲解的,如果大家觉得这样还是不能理解的话,关注我的公众号,后台回复“MVP”即可获取demo源码学习,感谢。Demo 主要使用retrofit2+okhttp3+RxJava2+RxLifecycle+Butterknife+GreenDao3.0+MVP框架设计,可以在Android studio 3.0上运行,项目还使用ConstraintLayout布局等等新技术;
原创不易,如果觉得写得好,扫码关注一下点个赞,是我最大的动力。
关注我,一定会有意想不到的东西等着你:
每天专注分享Android、JAVA干货
备注:程序圈LT
微信扫一扫
关注该公众号