详解Android中的MVP架构分解和实现
1、概述
传统的android开发架构一般是mvc模式,
- model:业务逻辑和实体模型
- view:对应于布局文件
- controllor:对应于activity
单独从逻辑看起来非常好,与我们做web开发时,开发模式类似,但在实际开发中,view对应于布局文件,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在activity中,activity既像view又像controller(mvvp架构中包括数据绑定),导致activity中职责太重,耦合度大。修改和维护起来非常麻烦。
2、mvp介绍
mvp架构中,view 对应于activity,负责view的绘制以及与用户交互
model 依然是业务逻辑和实体模型,presenter 负责完成view于model间的交互。
(1)model层
模型层之中做的工作是具体业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就需要实现一个interface来松耦合了。
(2)view层
视图层体现的很轻薄,负责显示数据、提供友好界面跟用户交互就行。mvp下activity和fragment体现在了这一 层,activity一般也就做加载ui视图、设置监听再交由presenter处理的一些工作,所以也就需要持有相应presenter的引用。处理一些基本ui逻辑,判断是否为空。
(3)presenter层
presenter这一层处理着程序各种逻辑的分发,收到view层ui上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由model层做具体的业务操作。
mvp架构和mvc架构区别:
mvc中是允许model和view进行交互的,而mvp中,model与view之间的交互由presenter完成。还有一点就是presenter与view之间的交互是通过接口的。
3、mvp实现
百说不如一做。实现一个简单的登录操作。
项目结构如下:
(1)model层实现
首先实现user实体类:
package com.chunsoft.blogcontent.bean; /** * developer:chunsoft on 2017/2/7 11:19 * content:实体类 */ public class user { private string username; private string password; public string getusername() { return username; } public void setusername(string username) { this.username = username; } public string getpassword() { return password; } public void setpassword(string password) { this.password = password; } }
model层主要实现业务逻辑处理,在本文案例中,主要逻辑处理就是登录,抽取了一个接口和一个实现类,在login操作,模拟登录操作,thread.sleep()模拟耗时,由于是耗时操作,通过一个回调接口通知登录状态。
model层接口:
package com.chunsoft.blogcontent.model; import com.chunsoft.blogcontent.requestcallback; import com.chunsoft.blogcontent.bean.user; /** * developer:chunsoft on 2017/2/7 11:30 * email:chun_soft@qq.com * content:model层主要处理业务方法和实体模型 */ public interface loginmodel { void login(string username, string password, requestcallback<user> callback); }
model层接口实现:
package com.chunsoft.blogcontent.model.impl; import com.chunsoft.blogcontent.requestcallback; import com.chunsoft.blogcontent.bean.user; import com.chunsoft.blogcontent.model.loginmodel; /** * developer:chunsoft on 2017/2/7 11:31 * content:model层的实现 */ public class loginmodelimpl implements loginmodel{ @override public void login(final string username, final string password, final requestcallback<user> callback) { //模仿登录操作 new thread() { @override public void run() { try { thread.sleep(2*1000); } catch (interruptedexception e) { e.printstacktrace(); } if ("chunsoft".equals(username) && "123456".equals(password)) { user user = new user(); user.setusername(username); user.setpassword(password); callback.onsuccess(user); } else { callback.onfailure("登录失败"); } } }.start(); } }
回调接口:
package com.chunsoft.blogcontent; /** * developer:chunsoft on 2017/2/7 11:35 * content:回调接口 */ public interface requestcallback<t> { void onsuccess(t datas); void onfailure(string msg); }
(2)view层实现
对于view层接口定义,首先考虑功能上的操作,然后考虑:
- 该操作需要什么?(getusername等)
- 该操作的结果,对应的反馈?(tomainactivity等)
- 该操作过程中交互友好?( showloading)
view层接口:
package com.chunsoft.blogcontent.view; import com.chunsoft.blogcontent.bean.user; /** * developer:chunsoft on 2017/2/7 11:54 * email:chun_soft@qq.com * content:view层接口 */ public interface loginview { string getusername(); string getpassword(); void showloading(); void hideloading(); void tomainactvity(user user); void showfailederror(string msg); }
view层实现,其实就是activity,可以看到activity的代码量大大减少,且逻辑清晰:
package com.chunsoft.blogcontent; import android.os.bundle; import android.support.v7.app.appcompatactivity; import android.view.view; import android.widget.button; import android.widget.edittext; import android.widget.progressbar; import android.widget.toast; import com.chunsoft.blogcontent.bean.user; import com.chunsoft.blogcontent.presenter.impl.loginpresenterimpl; import com.chunsoft.blogcontent.view.loginview; public class mainactivity extends appcompatactivity implements loginview{ private edittext et_mobile,et_password; private progressbar pb; private button btn_login; private loginpresenterimpl mloginpresenter = new loginpresenterimpl(this); @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); et_mobile = (edittext) findviewbyid(r.id.et_mobile); et_password = (edittext) findviewbyid(r.id.et_password); pb = (progressbar) findviewbyid(r.id.pb); btn_login = (button) findviewbyid(r.id.btn_login); btn_login.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { mloginpresenter.login(); } }); } @override public string getusername() { return et_mobile.gettext().tostring(); } @override public string getpassword() { return et_password.gettext().tostring(); } @override public void showloading() { pb.setvisibility(view.visible); } @override public void hideloading() { pb.setvisibility(view.invisible); } @override public void tomainactvity(user user) { toast.maketext(this,user.getusername() + "登录成功",toast.length_short).show(); } @override public void showfailederror(string msg) { toast.maketext(this,msg,toast.length_short).show(); } }
(3)presenter层实现
presenter层是model层和view层的桥梁,本文中依然抽象出一个接口和一个实现类,定义时主要看该功能有什么操作,例如,登录:
presenter接口:
package com.chunsoft.blogcontent.presenter; /** * developer:chunsoft on 2017/2/7 11:49 * content:presenter层接口 */ public interface loginpresenter { void login(); }
presenter层实现:
package com.chunsoft.blogcontent.presenter.impl; import android.os.handler; import com.chunsoft.blogcontent.requestcallback; import com.chunsoft.blogcontent.bean.user; import com.chunsoft.blogcontent.model.loginmodel; import com.chunsoft.blogcontent.model.impl.loginmodelimpl; import com.chunsoft.blogcontent.presenter.loginpresenter; import com.chunsoft.blogcontent.view.loginview; /** * developer:chunsoft on 2017/2/7 11:50 * content:presenter层实现 */ public class loginpresenterimpl implements loginpresenter { private loginview loginview; private loginmodel loginmodel; private handler mhandler = new handler(); //在构造函数中初始化 public loginpresenterimpl(loginview loginview) { this.loginmodel = new loginmodelimpl(); this.loginview = loginview; } @override public void login() { loginview.showloading(); loginmodel.login(loginview.getusername(), loginview.getpassword(), new requestcallback<user>() { @override public void onsuccess(final user datas) { //登录成功 mhandler.post(new runnable() { @override public void run() { loginview.tomainactvity(datas); loginview.hideloading(); } }); } @override public void onfailure(final string msg) { //登录失败 mhandler.post(new runnable() { @override public void run() { loginview.showfailederror(msg); loginview.hideloading(); } }); } }); } }
presenter层是model层和view层的桥梁,model层和view层不直接通信,所以presenter层需要model层和view层的实现类,从view层中获取重要参数,交给model 层调用业务逻辑处理,执行后的结果和反馈再交给view层去展示。
本文是简单的用mvp架构实现登录操作,而目前主流开发,将rxjava、retrofit和mvp结合进行开发,逻辑更加清晰,下篇文章将详细介绍这部分实现。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。