概述
认识MVP模式
MVP 模式实际上指的是 Model-View-Presenter 主要的目的是为了划分各个模块的负责区域,分工明确,使代码清晰了很多。也是为了减少 Activity 中代码,使其没有那么臃肿,提高测试性,主要的分工如下:
View 主要是负责显示数据和与用户进行交互,这可以是一个 Activity 或者是一个 Fragment,一个 android.view.View 或者是一个 Dialog。
Model 是数据源层,负责对数据进行存储,检索之类的操作。
Present 是 View 和 Model 进行交互的中间桥梁,负责 Model 和 View 两者之间的处理,也就是说从Model中获取的数据然后传递给 View,起到一个中间人的作用,也是在 MVP 模式中处理复杂逻辑的地方,后台任务也是它负责的。
为什么要使用 MVP 模式?
使其尽可能的简单
- 把复杂的任务分解成许多个简单小任务来执行
- 分解成的小任务 bug 比较少
- 减少测试时间
后台任务不和 Activity 关联
当你需要写一个 Activity,Fragment 或者一个自定义 View 的时候,你可以将所有和后台相关的方法放在一个外部类或者静态类中,这样你的后台任务就不会和Activity有关联,也不存在内存的泄漏的问题。
MVP 模式说明
其实在 MVP 中 Activity 对应的就是 View,把 Activity 中的 UI 逻辑抽象成 View 接口,在 View 中进行 UI 设计和简单的逻辑处理,Model 是业务逻辑和实体模型的实现,Presenter 负责完成View于Model间的交互(在这里进行复杂的逻辑处理),图片来自这里
由上图可以看出,在 MVP 模式中 Model 和 View 是不能直接交互的,而是通过 Presenter这个中间桥梁进行交互, MVP 和 MVC 模式最大的区别就在于此。也可以看出View和Presenter是一对一的关系,Model 可以为不同的 Presenter 提供数据服务。一般来说 Presenter 与 View 的交互是通过接口来进行的,这样有利于添加单元测试。
MVP 实例讲解
说了那么多还是用一个 Demo 来说一下,这样就比较好理解了。就用最简单的例子来说吧,做的是一个登录界面,输入账号和密码,账号密码输入正确的话则提示登录成功,反之则登录失败。效果图如下
登陆界面项目结构
项目结构从项目结构可以直接看出来,首先必须是要有实体类,然后就是 Model 的接口和实例,里面便是业务类中的实现方法,还有就是 View 的接口和实例,里面是负责 UI 的绘制和用户进行交互的逻辑,最后便是 Presenter,这里面作为 Model 和 View 的中间协调部分,负责两者之间的业务逻辑处理,复杂的逻辑处理一般都在这里进行编写。
实体类
首先是实体类的代码,实体类是必须有的就不用多说了
package com.example.xiaozhang.userloginactivity;
/**
* Created by xiaozhang on 2016/11/3.
*/
//创建实体类,实体类必须有的!!!
public class UserBean {
private String UserName;
private String PassWord;
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getPassWord() {
return PassWord;
}
public void setPassWord(String passWord) {
PassWord = passWord;
}
}
Model
在 Model 中有一个业务的接口,处理逻辑交给 Presenter 就行了。
package com.example.xiaozhang.userloginactivity.Model;
import com.example.xiaozhang.userloginactivity.UserBean;
/**
* Created by xiaozhang on 2016/11/3.
*/
//Model接口------业务逻辑或者实体型接口
public interface IUserLoginModel {
void Login(UserBean mUserBean);
}
为了能让点击登录后有提示,需要一个自定义 Listener 接口用来显示在屏幕上作为提醒,代码逻辑如下
package com.example.xiaozhang.userloginactivity.Model;
/**
* Created by xiaozhang on 2016/11/3.
*/
public interface IUserLoginListener {
void loginListener(boolean status);
}
最后是Model类中的业务类的逻辑编写
package com.example.xiaozhang.loginactivity.Model;
import com.example.xiaozhang.loginactivity.UserBean;
/**
*
Created by xiaozhang on 2016/11/3.
*/
public class UserLoginModel implements IUserLoginModel {
private String UserName;
private String PassWord;
private IUserLoginListener LoginListener;
public UserLoginModel(IUserLoginListener loginListener){
this.LoginListener = loginListener;
}
@Override public void Login(UserBean mUserBean) {
boolean status = false;
UserName = mUserBean.getUserName();
PassWord = mUserBean.getPassWord();
if ("admin".equals(UserName)&&"123456".equals(PassWord))
status = true;
LoginListener.loginListener(status);
}
}
View
View 和 Presenter 交互是通过接口的行形式,不过在写这个接口之前需要想一想需要实现的功能有哪些。
登录功能上肯定要有用户名和密码
String getUserName();
String getPassWord();
重置功能上也是要有清除用户名和密码
void clearUserName();
void clearPassWord();
还有就是点击登录按钮后显示是否成功登录的消息提示
void showMessage(String Message);
整合一下就是一个 View 接口的所有实现代码了
package com.example.xiaozhang.userloginactivity.View;
/**
* Created by xiaozhang on 2016/11/3.
*/
public interface IUserLoginActivity {
String getUserName();
String getPassWord();
void clearUserName();
void clearPassWord();
void showMessage(String Message);
}
后面就是写实现类了,前面说过了 Activity 对应的就是 View 的实现类,所以在 Activity中写实现类的逻辑
package com.example.xiaozhang.userloginactivity.View;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;import android.widget.EditText;
import android.widget.Toast;
import com.example.xiaozhang.userloginactivity.Presenter.UserLoginPresenter;
import com.example.xiaozhang.userloginactivity.R;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginActivity {
private EditText mInputUserName;
private EditText mInputPassWord;
private Button mLogin;
private Button mReset;
//这里需要注意下,没有 Presenter 的话前面这些都白写了,所以一定要创建实例!
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mInputUserName = (EditText) findViewById(R.id.edit_input_Account);
mInputPassWord = (EditText) findViewById(R.id.edit_input_PassWord);
mLogin = (Button) findViewById(R.id.btn_Login);
mReset = (Button) findViewById(R.id.btn_Reset);
mLogin.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
//复杂的逻辑交给Presenter
mUserLoginPresenter.login();
}
});
mReset.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
//复杂的逻辑交给presenter
mUserLoginPresenter.Reset();
}
});
}
@Override public String getUserName() {
return mInputUserName.getText().toString();
}
@Override public String getPassWord() {
return mInputPassWord.getText().toString();
}
@Override public void clearUserName() {
mInputUserName.setText("");
}
@Override public void clearPassWord() {
mInputPassWord.setText("");
}
@Override public void showMessage(String Message) {
Toast.makeText(this, Message, Toast.LENGTH_LONG).show();
}
}
Presenter
前面也提到了 Presenter 是 View 和 Model 进行交互的中间桥梁,这也要看你在你的代码里需要实现的是什么功能,在这里实现的登录和重置功能的实现以及点击登录后是否能成功登录出现的提示消息
package com.example.xiaozhang.userloginactivity.Presenter;
import com.example.xiaozhang.userloginactivity.Model.IUserLoginModel;
import com.example.xiaozhang.userloginactivity.Model.IUserLoginListener;
import com.example.xiaozhang.userloginactivity.Model.UserLoginModel;
import com.example.xiaozhang.userloginactivity.UserBean;
import com.example.xiaozhang.userloginactivity.View.IUserLoginActivity;
/**
* Created by xiaozhang on 2016/11/3.
*/
public class UserLoginPresenter implements IUserLoginListener{
private IUserLoginModel mIUserLoginModel;
private IUserLoginActivity mIUserLoginActivity;
public UserLoginPresenter(IUserLoginActivity mIULoginActivity) {
this.mIUserLoginActivity = mIULoginActivity; //这里命名后来发现不好区分,所以改了。。
mIUserLoginModel = new UserLoginModel(this);
}
public void login() {
UserBean mUserBean = new UserBean();
mUserBean.setUserName(mIUserLoginActivity.getUserName());
mUserBean.setPassWord(mIUserLoginActivity.getPassWord());
mIUserLoginModel.Login(mUserBean);
}
public void Reset() {
mIUserLoginActivity.clearPassWord();
mIUserLoginActivity.clearUserName();
}
@Override public void loginListener(boolean status) {
String Message;
if (status)
Message= "登录成功";
else
Message= "登录失败,请检查账号密码是否正确";
mIUserLoginActivity.showMessage(Message); }
}
总结
以上便是我对MVP的初步认识,毕竟自己也是刚接触这个不久,所以写的不好还请指导。对于刚接触到MVP模式还是有很多的问题,只能参考写出这么一个简单的Demo,后面也会从接触到的项目中学习到MVP的用法,到时候也会写出来和大家分享。
网友评论