初入MVP框架
来源:互联网 发布:mac任务栏图标太多 编辑:程序博客网 时间:2024/06/06 02:20
1.MVP介绍
哥看了很多关于介绍MVP构架博客,都觉得新手不容易理解,SO,决定写一篇MVP的博客.
什么是MVP?
Model:数据.负责数据的处理和输出.
VIew:视图.就是UI界面,即Activity.负责返回UI的信息和展示.
Presenter:主持者.接收View的逻辑业务和Model的数据,并处理它们之间的信息,并管理View的状态.
IView:View的接口给予Presenter调用进行UI逻辑的处理与View&Model之间的信息交互.
IPresenter:Presenter的接口,给予View调用,当UI的业务来临时,View通过调用Presenter接口完成展示(处理好的逻辑和数据等).
众所周知写程序都想要高内聚低耦合,在Android中使用MVC构架,Model与View之间的交互导致了模块之间过度的耦合,维护和debug比较困难.从上面的图可以看到MVP很好地隔离了Model和View.View与Model之间无耦合性.这是MVP最大的优点.
2.Example.
我们通过一个简单的用户登入界面进行解析MVP框架.
(一)Model
(1)User-实体类
首先写好实体类:两个数据 账号 和 密码.
package com.fengjie.mvptest.model.bean;/** * @author Created by FengJie on 2016/11/7-16:07. * @brief 用户实体类 * @attention */public class User{ private String account; private String password; public String getAccount () { return account; } public void setAccount ( String account ) { this.account = account; } public String getPassword () { return password; } public void setPassword ( String password ) { this.password = password; }}
(2)ITOVIew-预留给View的接口
我们指定当Model验证密码后,便需要显示登入成功要将实体类返回到Presenter和在View展现登入失败,登入失败也展现,所以我们先要预留一个接口给View
package com.fengjie.mvptest.model.deal;import com.fengjie.mvptest.model.bean.User;/** * @author Created by FengJie on 2016/11/7-16:10. * @brief 预留接口给View * @attention */public interface IToView{ public void loginSuccess( User user ); //登入成功方法 public void loginFaild(); //登入失败方法}
(3)Biz-事务(数据处理)类
package com.fengjie.mvptest.model.deal;import com.fengjie.mvptest.model.bean.User;/** * @author Created by FengJie on 2016/11/7-16:11. * @brief 对于实体数据和业务逻辑进行处理 * @attention */public class Biz{ public void login ( final String account, final String password, final IToView IToView ) { new Thread() //开启子线程模拟耗时操作 { @Override public void run () { //open a Thread try { Thread.sleep(2000); //delay 2 second } catch( Exception e ) { e.printStackTrace(); //print Exception } //Simulate login succeed situation. if ( "123".equals(account) && "123".equals(password) ) { User user = new User(); //instant of class user.setAccount(account); user.setPassword(password); IToView.loginSuccess(user); //use interface method. } else { IToView.loginFaild(); //use interface method. } } }.start(); }}
(二)View
(1)IUserLoginView-View的接口
View的接口主要是确定事务.
首先确定View的事务:负责返回用户和密码的数据,显示和隐藏进度条.
package com.fengjie.mvptest.view;import com.fengjie.mvptest.flag.Flag;/** * @author Created by FengJie on 2016/11/7-16:10. * @brief View数据交互-获得用户名和密码 显示和隐藏进度条 * @attention */public interface IUserLoginView{ public String getAccount (); public String getPassword (); public void setProgressBarVisibility ( final int VIEW_FLAG ); public void showToastInfo ( Flag flag);}
(2)UserLoginActivity
实现定义的接口,供于Precenter调用
package com.fengjie.mvptest.view;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.EditText;import android.widget.ProgressBar;import android.widget.Toast;import com.fengjie.mvptest.R;import com.fengjie.mvptest.flag.Flag;import com.fengjie.mvptest.presenter.IPresenter;import com.fengjie.mvptest.presenter.Presenter;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;public class UserLoginActivity extends AppCompatActivity implements IUserLoginView{ @BindView ( R.id.id_et_username ) protected EditText et_username; @BindView ( R.id.id_et_password ) protected EditText et_password; @BindView ( R.id.id_pb_loading ) protected ProgressBar pgb_loading; private IPresenter mPresenter = new Presenter(this); @Override protected void onCreate ( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); ButterKnife.bind(this); } /** * OnClick可以直接绑定点击事件,不必先获取控件 * @param view */ @OnClick(R.id.id_btn_login) protected void OnClick(View view) { mPresenter.loginDeal(); } @Override public String getAccount () { return et_username.getText().toString(); } @Override public String getPassword () { return et_password.getText().toString(); } @Override public void setProgressBarVisibility (final int VIEW_FINAL_VALUE) { pgb_loading.setVisibility(VIEW_FINAL_VALUE); } @Override public void showToastInfo ( Flag flag) { switch ( flag ) { case ADD_SUCCEED: Toast.makeText(this, et_username.getText().toString() + " login success", Toast.LENGTH_SHORT).show(); break; case ADD_FAILED: Toast.makeText(this, et_username.getText().toString() + " login failed", Toast.LENGTH_SHORT).show(); break; default:return; } }}
(三)Presenter
(1)IPresenter-Presenter接口
确定View与Model之间的交互事件:就是用户登入处理.
package com.fengjie.mvptest.presenter;/** * @author Created by FengJie on 2016/11/25-13:10. * @brief * @attention */public interface IPresenter{ public void loginDeal ();}
(2)Presenter
处理过程
- 调用View接口->显示进度条
- 调用Biz->实现将View返回的数据进行处理,同时通过预留的接口间接对View的下一步UI逻辑进行了处理.
逻辑太清晰了~~~~
也就是说Activity的一个UI业务来临时,只需要通过调用Presenter接口对应的一个方法就能实现处理了!!!这也使得我们的Activity不臃肿.
package com.fengjie.mvptest.presenter;import android.os.Handler;import android.view.View;import com.fengjie.mvptest.flag.Flag;import com.fengjie.mvptest.model.bean.User;import com.fengjie.mvptest.model.deal.Biz;import com.fengjie.mvptest.model.deal.IToView;import com.fengjie.mvptest.view.IUserLoginView;/** * @author Created by FengJie on 2016/11/7-16:07. * @brief 负责完成View与Model间的交互 * @attention */public class Presenter implements IPresenter{ private IUserLoginView mIUserLoginView; //view interface private Biz mBiz; //model class private Handler mHandler = new Handler(); //begin thread public Presenter ( IUserLoginView IUserLoginView ) { mIUserLoginView = IUserLoginView; mBiz = new Biz(); //instance Biz class } @Override public void loginDeal () { mIUserLoginView.setProgressBarVisibility(View.VISIBLE); //show the bar. mBiz.login(mIUserLoginView.getAccount(), mIUserLoginView.getPassword(), new IToView(){ /**achieve interface*/ /**login succeed**/ @Override public void loginSuccess ( final User user ) { mHandler.post(new Runnable() { @Override public void run () { mIUserLoginView.showToastInfo(Flag.ADD_SUCCEED); //give flag mIUserLoginView.setProgressBarVisibility(View.GONE); //hide ProgressBar } }); } /**login failed**/ @Override public void loginFaild () { mHandler.post(new Runnable() { @Override public void run () { mIUserLoginView.showToastInfo(Flag.ADD_FAILED); mIUserLoginView.setProgressBarVisibility(View.GONE); } }); } }); }}
总结
View与Presenter关系非常紧密, 相互调用, 并且一一对应. Presenter支持单元测试, View被抽象成若干显示接口, 供Presenter调用, 当View的业务来临只需要调用Presenter便能进行处理,View处理Android逻辑, Presenter处理UI逻辑. View和Presenter的接口信息, 放置在一个逻辑清晰的接口类(合同)中.
简单说View只要返回UI逻辑业务,Model只要处理好数据业务,Presenter只要处理好两者之间的交互并进行展现!
如果有帮助,请赞我的GiuHub和博客
源码下载:https://github.com/MadJieJie/MVPTest.git
- 初入MVP框架
- MVP框架
- mvp框架
- MVP框架
- 初入Hibernate框架<一>
- 初入Hibernate框架<二>
- 初入Hibernate框架<三>
- 初入MyBatis框架<一>
- 初入MyBatis框架<二>
- 初入MyBatis框架<三>
- 初入spring源码--整体框架
- MVC框架、mvp
- android MVP框架
- Android的MVP框架
- android 框架 MVP
- [androiod]_[MVP框架]
- MVP框架分析
- MVP框架设计详解
- CSS3实战开发:手把手教大家折角效果实战开发
- Island Perimeter
- Java中的I/O流及利用I/O流实现文件复制功能
- SET NEWNAME FOR DATABASE TO恢复数据库
- [读书笔记]30 天自制操作系统 day2 汇编语言学习与Makefile入门
- 初入MVP框架
- 如何关闭html页面上的iframe页面
- 开发项目之遇到eayui 中window panel 超过父页面的问题
- iOS 导航栏的那些事儿
- 用过滤器 +Session 会话权限控制详解
- Android 系统自动重启Bug(高通平台)
- win7 64位 plsql “无法解析指定的连接标识符”
- Dijkstra与spfa模板
- LeetCode 394. Decode String 题解