MVP设计模式从简单实现
才疏学浅初学者,在学习过程中总发现之前学过并且自认为很理解的一个模式,过段时间又忘记了,故想希望学得更扎实点又方便日后忘记了方法回想所以想到了写,借用****宝地记录一下学习笔记。
一:简单谈下MVC和MVP的异同:
MVC | MVP | ||
model | 模型:业务逻辑和实体模型 | model | 模型:依然是业务逻辑和实体模型 |
view | 视图:对应于布局文件 | view | 视图:处理UI控件;对应于Activity,负责View的绘制以及与用户交互 |
Controller | 控制器:操作model和view;控制业务流程;对应于Activity | presenter | 中介,负责完成View于Model间的交互;控制业务流程 |
由图看出,mvp和mvc最明显的区别就是将MVC的M和V的交互,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成 ,最大的好处就是降低了耦合度;
帮助理解:
A : MVP的核心思想: MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口;Model类还是Molder;
B:使用MVP模式的话,Activity的工作就简单了;Activity只用来响应生命周期,其他工作都丢到Presenter中去控制;实际业务工作在Model中完成;
二:代码实现:
android中MVP核心思想:ctivity中UI逻辑抽象成View接口View接口,业务逻辑抽象成Persenter接口,Model实心具体的业务;
本文分三个例子逐步加深对MVP的理解;
例一:MVP设计基础;
例二:MVP抽象+泛型设计;
例三:MVP代理模式高级运用;
---------------------------------------------例一:MVP的 基础实现--------------------------------------
需要实现的几个类: M层:LoginModel: 实现登陆的实际操作;
P层 :LoginPresenter:实现M层的V层的关联;
V层:LoginView:实现业务逻辑,只下命令,自己不做事;
public class LoginModel { public void login(String name, String pass, final Callback callback){ OkHttpUtils .get() .url("xxxxxxx") .addParams("username", "hyman") .addParams("password", "123") .build() .execute(new StringCallback() { @Override public void onError(Call call, Exception e, int id) { callback.onError(call,e,id); } @Override public void onResponse(String response, int id) { callback.onResponse(response,id); } }); } /** * 回调登陆请求结果 */ interface Callback{ void onError(Call call,Exception e,int id); void onResponse(String response,int id); } } |
interface LoginView { void onLoginResult(String response); void onErro(Exception e); }
/* 有两个特点: * 特点一:持有M层的引用; * 特点二:持有V层的引用; */ public class LoginPresenter { //持有M层的引用 private LoginModel model; //持有V层的引用 private LoginView view; public LoginPresenter(){ this.model=new LoginModel(); } //-----------------P层提供M层和V层关联的方法------------------ public void attachView(LoginView view){ this.view=view; } public void detachView(){ this.view=null; } public void pLogin(String name, String pass){ this.model.login(name, pass, new LoginModel.Callback() { @Override public void onError(Call call, Exception e, int id) { if (view!=null){ view.onErro(e); //response回调给了实现LoginView的activity的onLoginResult()方法; } } @Override public void onResponse(String response, int id) { if (view!=null){ view.onLoginResult(response); //response回调给了实现LoginView的activity的onLoginResult()方法; } } }); } } |
public class LoginActivity extends AppCompatActivity implements LoginView { private LoginPresenter presenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo1); presenter=new LoginPresenter(); presenter.attachView(this); findViewById(R.id.login).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { presenter.pLogin("wyj","pass"); } }); } @Override public void onLoginResult(String response) { //参数response是登陆成功返回的参数成功 Toast.makeText(LoginActivity.this, "登陆成功", Toast.LENGTH_SHORT).show(); } @Override public void onErro(Exception e) { Toast.makeText(LoginActivity.this, "登陆失败"+e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { super.onDestroy(); presenter.detachView(); } } |
--------------------------------------------例二:MVP的泛型设计--------------------------------------
分析:如果项目中有50个Activity,就需要绑定和解除50次;解决方案就是将共有逻辑抽象出来通过泛型实现(类型不唯一); demo中相比之下增加了MvpView,MvPresenter,MvpBasePresenter这几个类;将demo1中其他activity同样用得到的逻辑提出来放在最外层实现;
public interface MvpView {
}
interface LoginView extends MvpView{ void onLoginResult(String response); void onErro(Exception e); }
public interface MvpPresenter<V extends MvpView>{ void attachView(V view); //必须是MvpView的子类 void detachView(); }
public class MvpBasePresenter<V extends MvpView> implements MvpPresenter<V>{ private V view; public V getView(){ return view; } @Override public void attachView(V view) { this.view=view; } @Override public void detachView() { this.view=null; } }
public class LoginPresenter extends MvpBasePresenter<LoginView>{ //持有M层的引用 private LoginModel model; public LoginPresenter(){ this.model=new LoginModel(); } //-----------------P层提供M层和V层关联的方法------------------ public void pLogin(String name, String pass){ this.model.login(name, pass, new LoginModel.Callback() { @Override public void onError(Call call, Exception e, int id) { if (getView()!=null){ getView().onErro(e); //response回调给了实现LoginView的activity的onLoginResult()方法; } } @Override public void onResponse(String response, int id) { if ( getView()!=null){ getView().onLoginResult(response); //response回调给了实现LoginView的activity的onLoginResult()方法; } } }); } }
public class LoginModel { public void login(String name, String pass, final Callback callback){ OkHttpUtils .get() .url("https://www.baidu.com/") .addParams("username", name) .addParams("password", pass) .build() .execute(new StringCallback() { @Override public void onError(Call call, Exception e, int id) { callback.onError(call,e,id); } @Override public void onResponse(String response, int id) { callback.onResponse(response,id); } }); } /** * 释放资源 */ public void close() { } /** * 回调登陆请求结果 */ interface Callback{ void onError(Call call, Exception e, int id); void onResponse(String response, int id); } }
public class LoginActivity extends AppCompatActivity implements LoginView { private LoginPresenter presenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo2); presenter=new LoginPresenter(); presenter.attachView(this); findViewById(R.id.login).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { presenter.pLogin("wyj","pass"); } }); } @Override public void onLoginResult(String response) { //参数response是登陆成功返回的参数成功 Toast.makeText(LoginActivity.this, "登陆成功", Toast.LENGTH_SHORT).show(); } @Override public void onErro(Exception e) { Toast.makeText(LoginActivity.this, "登陆失败"+e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { super.onDestroy(); presenter.detachView(); } }
--------------------------------------------例三:MVP的代理模式--------------------------------------
---------------------------------------------例一:MVP的 基础实现--------------------------------------
思路: