MVP模式
MVP是一种开发模式,是Model+View+Presenter的简称
众所周知,在Android开发中,随着项目规模的增大,Activity需要执行的任务越来越重,导致Activity越来越臃肿。为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生。
为何引入MVP模式
在Android开发中,Activity并不是一个标准(MVC中)的Controller,也不是一个单纯(MVC中)的View,它不仅负责界面的绘制和数据的初始化,还要负责响应所有的交互行为。不止这些,还要进行一些复杂的逻辑操作……这就造成两个很明显的麻烦。一是Activity会很臃肿、很凌乱;二是造成高耦合,代码很难复用。
要解决以上问题,就需要把Activity所负责的那些操作给分开,也就是分层,那么分层的标准是什么呢?标准就是MVP。将逻辑操作都放在Presenter中,再把跟数据相关的操作放到Model中,这样一来,Activity中就只剩下View的绘制了。当然,必须通过Presenter把Model与View关联起来,不能让View直接与Model产生关系,必须通过Presenter关联。
利用MVP进行Android开发小Demo
来个小Demo
功能:用EditText中的内容创建用户,点“保存”的时候保存起来,点“获取”的时候再显示出来
界面截图,如下图
项目结构,如下图
代码说明
1.User.java
,用户实体类
public class User {
private int id;
private String name;
private String sex;
public User() {
}
public User(int id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
2.UserModel.java
,Model接口
public interface UserModel {
void saveUser(int id, String name, String sex);
User loadUser();
}
3.UserModelImpl.java
,Model的实现类(负责用户数据的处理)
public class UserModelImpl implements UserModel {
private List<User> mUserList;
public UserModelImpl() {
mUserList = new ArrayList<>();
}
@Override
public void saveUser(int id, String name, String sex) {
if (null == mUserList) {
return;
}
mUserList.add(new User(id, name, sex));
}
@Override
public User loadUser() {
return null != mUserList ? mUserList.get(mUserList.size() - 1) : null;
}
}
4.UserView.java
,View接口
public interface UserView {
int getId();
String getName();
String getSex();
void setName(String name);
void setSex(String sex);
}
5.UserPresenter.java
,Presenter层,同时持有对应View层和对应Model层成员变量,从而达到关联View与Model的目的
public class UserPresenter {
private static final String TAG = "UserPresenter";
private UserView mUserView;
private UserModel mUserModel;
public UserPresenter(UserView userView) {
mUserView = userView;
mUserModel = new UserModelImpl();
}
public void saveUser() {
mUserModel.saveUser(mUserView.getId(), mUserView.getName(), mUserView.getSex());
}
public void loadUser() {
User user = mUserModel.loadUser();
mUserView.setName(user.getName());
mUserView.setSex(user.getSex());
}
}
5.MVPActivity.java
,真正的View层,需要实现对应的View接口,并且持有对应的Presenter成员变量,这样才能将数据传递给Presenter,并且与Presenter交互
public class MVPActivity extends Activity implements UserView {
@BindView(R.id.et_name)
EditText etName;
@BindView(R.id.et_sex)
EditText etSex;
@BindView(R.id.btn_save)
Button btnSave;
@BindView(R.id.btn_load)
Button btnLoad;
private Random random;
private UserPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
ButterKnife.bind(this);
random = new Random();
mPresenter = new UserPresenter(this);
}
@OnClick({R.id.btn_save, R.id.btn_load})
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_save:
mPresenter.saveUser();
break;
case R.id.btn_load:
mPresenter.loadUser();
break;
}
}
@Override
public int getId() {
return random.nextInt(101) + 1;
}
@Override
public String getName() {
return etName.getText().toString();
}
@Override
public String getSex() {
return etSex.getText().toString();
}
@Override
public void setName(String name) {
etName.setText(name);
}
@Override
public void setSex(String sex) {
etSex.setText(sex);
}
}
就这样,一个简单的MVP小Demo就完成了。其实可以把View层接口看作一个回调接口,该接口的方法都在相应的Activity中实现,而在Presenter中通过该View层对象调用相应方法时,就能与Activity发生交互,也就是View与Presenter之间的交互;除此之外,在Presenter中通过Model层对象调用相应的方法,就能实现Presenter与Model的交互。如此一来,Activity就只负责界面的绘制与展示,Presenter则只负责逻辑的相关操作,Model层只负责与数据相关的操作(比如与网络交互等),这就达到MVP模式的标准。
在此声明,以上只是个人见解,作为笔记而已。不喜勿碰!!