浅谈MVP实现Android应用层开发

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

【工匠若水 】

背景

之所以要谈这个话题是因为你在开发App时可能会发现,Activity担负的责任非常之重,如果站在MVC框架角度看自己开发的App,一般xml布局文件科Activity的setContentView等充当了View角色,Activity其他代码充当了Controller角色,其他数据来源(数据库等)充当了Model角色。所以你会发现Activity违背单一职责原则,负担过重。同时如果要测试逻辑数据层会发现比较难编写测试用例。由此来构想,有没有一种解耦的方法呢?

有,那就是MVP框架。

MVP架构

MVP就是Model-View-Presenter。其实不用做太多解释,如下图所示你就能明白大致:

如上图所示可以看见MVP模式需要具备如下三要素:

程序猿的纠结—MVP与MVC

看完上面两段,你可能会疑惑MVP,还有一个MVC,他两啥关系?

那再来看下MVC吧!

MVC架构

MVC框架认为软件可以分成如下三个部分:

如下图很直观的展示了MVC框架的核心:

View传送指令到Controller,Controller完成业务逻辑后,要求Model改变状态,Model将新的数据发送到View,用户得到反馈。

MVP与MVC对比

这时候你会发现MVC与MVP的结构图都有很大区别,具体区别如下:

MVP架构:

View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。 Presenter与View的交互是通过接口来进行的。 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。

MVC架构:

View可以与Model直接交互。 Controller是基于行为的,并且可以被多个View共享。 可以负责决定显示哪个View。

总结

MVC与MVP很相似,但又有很大区别,站在不同分析角度会有不同的观点,这里只是站在基于Android App代码下来分析的结果。

MVP架构的Android应用实战:

完整工程代码点我进入下载页面

背景:如下案例模拟一次用户交互存取数据的过程,,用户输入数据后点击保存,然后点击获取数据将保存的数据获取的操作。 UI界面:

工程目录结构:

详细代码:

首先看model层代码,model层提供抽象接口,方便解耦,同时方便测试用例测试model的impl实现代码。如下展示了抽象接口和实现代码。

Model层抽象接口:

{//从数据提供者获取数据方法InfoBean getInfo();//存入数据提供者方法void setInfo(InfoBean info);}

Model层抽象实现:

{//模拟存储数据private InfoBean infoBean = new InfoBean();@Overridepublic InfoBean getInfo() {//模拟存储数据,真实有很多操作return infoBean;}(InfoBean info) {//模拟存储数据,真实有很多操作infoBean = info;}}

接着看View层代码,View层同样提供抽象接口,方便解耦,同时方便测试用例测试View的impl实现交互代码。如下展示了抽象接口的代码。

View层的抽象接口:

{//给UI显示数据的方法void setInfo(InfoBean info);//从UI取数据的方法InfoBean getInfo();}

这个时候其实你可以想想,写UI和逻辑的人可以完全分工,他们通过接口对接。Presenter的角色更像是一个设计模式的适配器类,负责对接UI与数据逻辑。所以不妨先看下Presenter的实现:

{private IInfoModel infoModel;private IInfoView infoView;public Presenter(IInfoView infoView) {this.infoView = infoView;infoModel = new InfoModelImpl();}(InfoBean bean) {infoModel.setInfo(bean);}() {//通过调用IInfoView的方法来更新显示,设计模式运用//类似回调监听处理infoView.setInfo(infoModel.getInfo());}}

这时候回过头看下View层代码,View层同样实现了View层提供的抽象接口(也就是Activity类,充当UI View)。

如下展示了View层的实现代码:

, View.OnClickListener{private EditText inputId, inputName, inputAddr;private Button saveBtn, loadBtn;private TextView infoTxt;private Presenter presenter;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();}() {presenter = new Presenter(this);inputId = (EditText) findViewById(R.id.id_input);inputName = (EditText) findViewById(R.id.name_input);inputAddr = (EditText) findViewById(R.id.addr_input);saveBtn = (Button) findViewById(R.id.input_confirm);loadBtn = (Button) findViewById(R.id.get_confirm);infoTxt = (TextView) findViewById(R.id.show);saveBtn.setOnClickListener(this);loadBtn.setOnClickListener(this);}(InfoBean info) {StringBuilder builder = new StringBuilder(“”);builder.append(info.getId());builder.append(“\n”);builder.append(info.getName());builder.append(“\n”);builder.append(info.getAddress());infoTxt.setText(builder.toString());}@Overridepublic InfoBean getInfo() {InfoBean info = new InfoBean();info.setId(Integer.parseInt(inputId.getText().toString()));info.setName(inputName.getText().toString());info.setAddress(inputAddr.getText().toString());return info;}(View v) {switch (v.getId()) {case R.id.input_confirm:presenter.saveInfo(getInfo());break;case R.id.get_confirm:presenter.getInfo();break;}}}

到此解耦并行开发的App编码工作已经完成,如下展示运行结果:

完整工程代码点我进入下载页面

总结无论才能知识多么卓着,如果缺乏热情,则无异纸上画饼充饥,无补于事。

浅谈MVP实现Android应用层开发

相关文章:

你感兴趣的文章:

标签云: