Android(安卓)MVP模式进阶版——拿去直接用
引言
如果对于mvp和mvc不太熟悉的童鞋,请花一点时间阅读下面文字内容,纯手工打些本人一点粗糙的见解。或者问问度娘多多学习。熟悉者可直接跳过看干货,撸代码阶段。
在说mvp之前,相信大家应该都熟悉了mvc(model 、 view 、 control)。在Android的架构中Activity,fragment,布局的xml相当于View。然而在实际的开发过程中,Android的View层任务太繁重,大家将V和C都糅杂在Activity、Fragment中,这就导致了在实际开发中View层太过累赘,一不小,几次代码迭代过后,一个Activity或者Fragment中的代码就有几千行,有时候修改个功能在笨重的代码中摸爬滚打半天才找到关键点,对于不熟悉代码的开发者来说(或者前人编写代码质量太低)那代码迭代接手后简直是妙不可言。所以将视图和业务逻辑代码分开势在必行。
基于这个现状,我们伟大的Google粑粑设计了一个更优的框架模式来解决这个问题。就是目前实际开发中火热的MVP模式(model 、 view 、presenter)。用presenter将model和view隔离开来,一切业务逻辑处理都是通过presenter来进行操作,也就是说presenter是视图的数据的桥梁,视图和数据相隔两端,“可远观而不可亵玩”。强制只能使用presenter作为“邮递员”来”通信“。
正文
上图最为直接,区别:mvc结构,一眼便知,model和view并没有隔离,view一只手悄悄的碰到了model层。而mvp中presenter完全垄断了与数据实体的”贸易“。视图要数据必须通过presenter。这样将业务逻辑剥离出去,视图层专注view的展现。
image image万事万物,有优点就有缺点,伟大的孟子大学者就曾说过”鱼与熊掌不可兼得“。
优点:最大的优点剥离了视图层和业务逻辑层,让各个类的分工更为明确,逻辑更为清晰,代码扩展性更高,后期代码迭代更新更加容易,同时也方便了单元测试的编写,以前将视图与业务混合在一起的时候,要写单元测试很多时候真的是无从下手。相对于MVP模式来说写单元测试就更加容易了。因为职责更加清晰,测试的目标就明确多了。
缺点:相对而言,MVP模式的代码量就多了,类文件也多了,简单的一个业务逻辑操作就要各方来配合协作(即是需要presenter 和 view的接口)。但是这个问题完全在可以接收的范围。完全符合Java的抽象封装设计原则(接口隔离,开闭原则,里氏代换不熟悉的童鞋阔以问问伟大的度娘)。
** 代码结构**
首先是View和presenter的接口,抽象出view对象的绑定方法。
IView.java
public interface IView { void bindView(); void UnbindView(); }
IPresenter.java
public interface IPresenter { void register(V view); void unRegister();}
BasePresenter实现IPresenter接口,为业务逻辑层presenter的基类。用弱引用来接收View的对象,在取消注册的时候销毁view对象,保证View不会造成内存泄漏。
BasePresenter.java
public class BasePresenter implements IPresenter {protected WeakReference iView;@Overridepublic void register(V view) { Log.i(TAG, "BasePresenter register: "); iView = new WeakReference(view);}@Overridepublic void unRegister() { Log.i(TAG, "BasePresenter unRegister: "); iView.clear();}
}
BaseActivity实现IView接口,为视图层的基类(也就是Activity的基类),这是一个抽象类,实现了视图层到业务逻辑层的绑定与解绑,抽象方法createPresenter()子类必须实现,来确保不通的业务逻辑层。
BaseActivity.java
public abstract class BaseActivityextends Activity implements IView{protected P iPresenter;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); bindView();}@Overrideprotected void onDestroy() { super.onDestroy(); UnbindView();}@Overridepublic void bindView() { iPresenter = createPresenter(); iPresenter.register(this);}@Overridepublic void UnbindView() { iPresenter.unRegister();}protected abstract P createPresenter();}
接下来是具体的使用MVP的流程了,定义三方交接接口
public interface DemoContract {interface View{ void demoView(String test);}interface Presenter{ void demoPresenter();}interface Model{ void demoModel(ModelListener modelListener); interface ModelListener{ void completed(String test); }}
}
视图层DemoActivity.java基层BaseAcitivity实现createPresenter()方法,DemoContract.View接口。
public class DemoActivity extends BaseActivity implements DemoContract.View {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iPresenter.demoPresenter();}@Overrideprotected DemoPresenter createPresenter() { return new DemoPresenter();}@Overridepublic void demoView(String test) { Toast.makeText(this, test, Toast.LENGTH_LONG).show();}
}
业务逻辑层DemoPresenter.java基层BasePresenter实现DemoContract.Presenter接口
public class DemoPresenter extends BasePresenter implements DemoContract.Presenter {DemoContract.Model model = new DemoModel();@Overridepublic void demoPresenter() { model.demoModel(new DemoContract.Model.ModelListener() { @Override public void completed(String test) { iView.get().demoView(test); } });}
}
数据实体层DemoModel.java实现DemoContract.Model接口,用接口回调异步返回数据。
public class DemoModel implements DemoContract.Model{@Overridepublic void demoModel(ModelListener modelListener) { modelListener.completed("mvp test");}
}
最后附上源码传送门:https://github.com/pffo/mvp
请大神多多指教
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- 安卓 SQLite数据库操作实例
- Git diff代码比较的高级技巧
- 一步步教你如何创建React Native的原生Android模块
- android用户界面编程技巧――如何使用Adapter
- Android(安卓)UI布局优化之ViewStub
- android studio调用JNI
- android 消息传递机制进阶EventBus的深入探究
- Android(安卓)仿知乎创意广告 广告还能这么玩?