浅析MVP模式
来源:互联网 发布:java参数引用传递 编辑:程序博客网 时间:2024/04/29 18:47
MVP模式已经流行很长一段时间了,以前只是听到关于MVP的一些东西,譬如:MVP是MVC的进化版,MVP模式让View层和Model层完全解耦了。
这里先简单回顾一下Android中MVC模式:M即是代表业务逻辑和实体模型;V即是代码对应的View,也就是界面;C即是代表控制层,对应着Activity或者Fragment;但是很多时候数据处理都在Activity或者Fragment中,View可以直接访问Model,这样就不可避免一些业务逻辑了,而且有许多业务逻辑都是在View层处理的,所以导致很多代码也就无法重用了。
MVP模式与MVC模式最大的区别就是View不与Model打交道,而是通过Presenter来与Model交互,而且Presenter实现的逻辑代码与具体View是没有关联的,它不属于任何具体的View,而只是通过约定好的接口来交互。
根据一个简单的例子来对MVP模式进行更深刻的理解,图1就是要实现的UI效果,一个简单的登陆界面:
图2是项目文件结构图:
图3是MVP示意图和项目中各类的对应关系,以便更好地理解:
解析:
- UserBean是实体类,这个没什么可以讲的,直接上代码:
public class UserBean { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
- Model部分是负责数据逻辑处理的部分,这个例子比较简单,就只有登陆这个功能而已,方便我们以后做业务拓展,我们先写一个UserModel 的接口UserModelInterface,代码如下:
public interface UserModelInterface { void login(String name,String password,LoginListener loginListener);}
UserModel 实现代码如下:
public class UserModel implements UserModelInterface { @Override public void login(String name, String password, LoginListener loginListener) { //判断用户名是否为空 if (TextUtils.isEmpty(name)){ loginListener.nameIsEmpty(); return; } //判断密码是否为空 if (TextUtils.isEmpty(password)){ loginListener.passwordIsEmpty(); return; } //用户名和密码都不为空的情况下执行登陆操作,这里就实现登陆的网络请求代码了,直接默认登陆成功,如果登陆失败则回调loginListener.loginFailed(); loginListener.loginSuccess(); }}
LoginListener 这个接口主要是用于Model和Presenter的交互,把Model的业务逻辑处理接口返回出去给Presenter,然后Presenter再通过接口(LoginView)把结果返回给View层,这大概就是MVP的模式的核心了,先不急,先上LoginListener的代码:
public interface LoginListener { void loginSuccess(); void loginFailed(); void nameIsEmpty(); void passwordIsEmpty();}
结合这个案例来讲,无非就两种结果,登陆成功或者失败,然后执行登陆之前要判断用户名和密码是否为空,所以就有以上四个方法了。
- 接下来看我们用于View(MVPLoginActivity)和Presenter(LoginPresenter)交互的接口–LoginView,这个接口主要是从分析界面来得到的业务逻辑,譬如:用户有在登陆成功后我们需要进行页面的跳转,登陆失败后的我们需要弹出一个Toast来提示用户,或者更改界面提示等等。所以就有以下的代码实现:
public interface LoginView { String getName(); String getPassword(); void setName(String name); void setPassword(String password); void loginSuccess();//登录成功 void loginFailed();//登录失败 void nameIsEmpty();//名字为空 void passwordIsEmpty();//密码为空}
- 既然说LoginView是用于View和Presenter的交互的,现在问题来了,LoginView是怎么来连接MVPLoginActivity和LoginPresenter的呢?其实很简单,只需要MVPLoginActivity去实现LoginView这个接口,直接上MVPLoginActivity代码:
public class MVPLoginActivity extends AppCompatActivity implements LoginView{ private AutoCompleteTextView email; private EditText passwordEt; private Button email_sign_in_button; private LoginPresenter loginPresenter=new LoginPresenter(this);//实例化Presenter @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); email= (AutoCompleteTextView) findViewById(R.id.email); passwordEt= (EditText) findViewById(R.id.password); email_sign_in_button= (Button) findViewById(R.id.email_sign_in_button); email_sign_in_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loginPresenter.login();//登录登录登录登录登录 } }); } @Override public String getName() { return email.getText().toString(); } @Override public String getPassword() { return passwordEt.getText().toString(); } @Override public void setName(String name) { email.setText(name); } @Override public void setPassword(String password) { passwordEt.setText(password); } @Override public void loginSuccess() { Log.i("ysc","loginSuccess"); } @Override public void loginFailed() { Log.i("ysc","loginFailed"); } @Override public void nameIsEmpty() { Log.i("ysc","nameIsEmpty"); } @Override public void passwordIsEmpty() { Log.i("ysc","passwordIsEmpty"); }}
在这个地方就出现了我们全面说了很多的用于View和Model交互的P(LoginPresenter)这个类了,在界面(MVPLoginActivity )实例化时也实例化LoginPresenter,在点击按钮时执行loginPresenter.login(),然后View就可以不用关系其他情况了,然后在下面看LoginPresenter的代码:
public class LoginPresenter { private LoginView loginView; private UserModel userModel; public LoginPresenter(LoginView loginView) { this.loginView = loginView; this.userModel=new UserModel(); } public void login(){ userModel.login(loginView.getName(), loginView.getPassword(), new LoginListener() { @Override public void loginSuccess() { loginView.loginSuccess(); } @Override public void loginFailed() { loginView.loginFailed(); } @Override public void nameIsEmpty() { loginView.nameIsEmpty(); } @Override public void passwordIsEmpty() { loginView.passwordIsEmpty(); } }); }}
先看构造方法
public LoginPresenter(LoginView loginView) { this.loginView = loginView; this.userModel=new UserModel(); }
先把Loginview传进来用户与view层的交互,再实例化Model(UserModel),前面有说过业务处理都在Model里,也就是userModel.login()这个方法,然后Model的处理结构通过接口LoginListener来告知LoginPreseter,LoginPresenter再通过Loginview来更新界面,这样就完成View与Model的完全解耦了。
- LoginView:就是写一些界面需要业务逻辑,然后可以实现相对应的UI操作。
- MVPLoginActivity:单纯的界面,实现LoginView接口,并且实例化Presenter。
- Presenter:LoginPreseter作为MVPLoginActivity和UserModel的中间层,把通过LoginView拿到的界面数据传给UserModel处理,UserModel处理完的结果返回回来之后,通过LoginView来更新界面或者做相应的UI操作。
- MVPLoginActivity和LoginPreseter,LoginPreseter和UserModel之间的交流都是通过接口来处理,前者通过LoginView,后者通过LoginListener。
- 从以上分析看来MVP模式确实完成了View层和Model的完全解耦
以上就是个人看过很多篇关于MVP方面的博客资料的后,动手写的demo,顺便也写成博客,欢迎多多指正。
- 浅析MVP模式
- 浅析MVP设计模式
- Android MVP设计模式浅析
- MVC、MVP、MVVM模式浅析
- 浅析android的mvp模式
- MVP设计模式浅析、实战
- Android开发中MVP模式浅析
- MVC、MVVM、MVP 框架设计模式浅析
- Android MVP 模式 理解与浅析
- 浅析前端MVC、MVP、MVVM模式
- MVP浅析
- MVP浅析
- MVP 浅析
- 浅析MVP(Model-View-Presenter)架构及开发模式
- 架构探险——Android MVP模式浅析
- 浅析前端开发中的 MVC/MVP/MVVM 模式
- 浅析前端开发中的 MVC/MVP/MVVM 模式
- Android MVP架构浅析
- C语言基础 进制的转换
- servlet 的destroy什么时候调用
- 微信开发中用dom4j解析消息时的错误
- 强制IE浏览器或WebBrowser控件使用指定版本显示网页
- Python any函数
- 浅析MVP模式
- 随机出数并排列
- android native hook 源码 及 解析
- Java Swing中的组件用final修饰
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- 1
- 十个数有序排列
- 2. Add Two Numbers 【M】【72】【leetcode】
- 15电气1班麻天骄