MVP模式 详解 案例
2016-09-04 21:33
232 查看
介绍
MVC: View:对应于布局文件 Model:业务逻辑和实体模型 Controllor:对应于Activity 实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,造成了Activity既像View又像Controller程序员对于MVP的普遍的认识是:代码很清晰,不过增加了很多类 当将架构改为MVP以后,Presenter的出现,将Actvity视为View层,Presenter负责完成View层与Model层的交互。现在是这样的:View 对应于Activity,负责View的绘制以及与用户交互 Model 依然是业务逻辑和实体模型 Presenter 负责完成View和Model间的交互 从并不标准的MVC到MVP的一个转变,减少了Activity的职责,简化了Activity中的代码,将复杂的逻辑代码提取到了Presenter中进行处理。与之对应的好处就是,耦合度更低,更方便的进行测试。MVC与MVP的一个区别示意图:其实最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的。
案例
Activity包(view包)
/** * 梳理此Activity所有需要的方法,将这些方法全部封装到一个接口中 * @author 白乾涛 */public interface IUserLoginView { public String getUserName(); public String getPassword(); public void clearUserName(); public void clearPassword(); public void toMainActivity(User user); public void showFailedError(); public void showLoading(); public void hideLoading();}/** * 简单来说,对Activity的所有操作(方法)都被剖离在了两个地方,一个是在IUserLoginView中,这里面都是对Activity的一些最基本的操作 * 另一个在Presenter中,比较复杂的【业务逻辑】都会放在这里(目的当然是减少Activity的代码逻辑) * 一定要明白,之所以将Activity中的这些方法剖离在IUserLoginView中,是为了在Presenter中能通过操作IUserLoginView来操作Activity(扩展性) * * @author 白乾涛 */public class UserLoginActivity extends Activity implements IUserLoginView, OnClickListener { private EditText id_et_username; private EditText id_et_password; private Button id_btn_login; private Button id_btn_clear; private UserLoginPresenter mUserLoginPrestener = new UserLoginPresenter(this);//这里是将IUserLoginView接口的实例(即Activity)传给了Presenter private ProgressBar id_progressbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_login); id_et_username = (EditText) findViewById(R.id.id_et_username); id_et_password = (EditText) findViewById(R.id.id_et_password); id_btn_login = (Button) findViewById(R.id.id_btn_login); id_btn_clear = (Button) findViewById(R.id.id_btn_clear); id_progressbar = (ProgressBar) findViewById(R.id.id_progressbar); id_btn_login.setOnClickListener(this); id_btn_clear.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.id_btn_login: //这里面的两个方法在Presenter中,当我们需要修改业务逻辑时,只需修改Prestener类中的相应方法即可! mUserLoginPrestener.login(); break; case R.id.id_btn_clear: mUserLoginPrestener.clear(); break; } } //****************************************************************************************** @Override public String getUserName() { return id_et_username.getText().toString(); } @Override public String getPassword() { return id_et_password.getText().toString(); } @Override public void clearUserName() { id_et_username.setText(""); } @Override public void clearPassword() { id_et_password.setText(""); } @Override public void toMainActivity(User user) { Toast.makeText(getApplicationContext(), user.getUsername() + "--登录成功", Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show(); } @Override public void showLoading() { id_progressbar.setVisibility(View.VISIBLE); } @Override public void hideLoading() { id_progressbar.setVisibility(View.INVISIBLE); }}
presenter包
/** * 这就是传说中的Prestener,这里面封装的都是Activity中复杂的业务逻辑 * @author 白乾涛 */public class UserLoginPresenter { private IUserBiz userBiz; private IUserLoginView userLoginView; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { }; }; //在构造Prestener时,需要传递一个IUserLoginView接口的实例(其实就是Activity),只有这样,Prestener才能对此实例进行操作 public UserLoginPresenter(IUserLoginView userLoginView) { this.userBiz = new UserBiz(); this.userLoginView = userLoginView; } public void login() { userLoginView.showLoading(); //为了更具扩展性及进一步解耦,具体的登录逻辑又通过同样的方式转移到了IUserBiz接口上(统一放在biz包下) userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final User user) { //需要再UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginFailed() { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailedError(); userLoginView.hideLoading(); } }); } }); } public void clear() { userLoginView.clearPassword(); userLoginView.clearUserName(); }}
bean包
/** * 一个业务bean,所有需要被操作的基本元素(不包括View)都应该定义在这里 * @author 白乾涛 */public class User { private String username; private String password; public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; }}
biz(业务)包
/** * 复杂的业务逻辑在这里定义:如,登录、忘记密码、联系客服 * @author 白乾涛 */public interface IUserBiz { public void login(String username, String password, OnLoginListener onLoginListener);}/** * 复杂业务逻辑的具体实现:如具体的登录代码在这里编写 * 这里面有一个回调 * @author 白乾涛 */public class UserBiz implements IUserBiz { @Override public void login(final String username, final String password, final OnLoginListener onLoginListener) { new Thread() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if ("username".equals(username) && "password".equals(password)) { User user = new User(); user.setUsername(username); user.setPassword(password); //成功时的回调 onLoginListener.loginSuccess(user); } else { //失败时的回调 onLoginListener.loginFailed(); } } }.start(); }}/** * 这个其实不算是MVP中的东西(但一般都会有),这是一个回调,当执行复杂逻辑的同时做一些回调处理 * @author 白乾涛 */public interface OnLoginListener { public void loginSuccess(User user); public void loginFailed();}
来自为知笔记(Wiz)
相关文章推荐
- 观察者模式_OBSERVER_案例详解
- 浅析MVP模式中V-P交互问题及案例分享
- Android MVP 模式 详解
- 详解MVP模式在Android开发中的应用
- MVP、MVP、 MVVM 设计模式详解
- Singleton_单列模式案例分析与详解
- MVP架构模式详解
- java设计模式案例详解:观察者模式
- MVP架构模式详解
- Android中MVC,MVP和MVVM三种模式详解析
- 浅析MVP模式中V-P交互问题及案例分享
- 详解Android MVP开发模式
- android设计模式之mvp详解
- java设计模式案例详解:工厂模式
- 设计模式MVP案例----省市查询
- 观察者模式_OBSERVER_案例详解
- 观察者模式_OBSERVER_案例详解
- android中MVP模式的小案例(一)
- android之MVP设计模式详解
- 王学岗csdn——MVP架构模式详解(一)