Android架构探究之MVP设计模式
0. MVP是有MVC衍化而来的,不熟悉MVC的同学可以看这篇文章
Android架构探究之MVC设计模式: 点击阅读
1. MVP模式介绍-Model-View-Persenter
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。[1]*
2. MVP与MVC的区别
MVP 流程图
通过该流程图我们可以看出Presenter层作为与MVC相似的Controller层处于 View层和Model层中间的位置。
.
所以Presenter在MVP中担任了一个“桥梁”的作用,控制与接收分别来自View层和Model层的指令与状态,将View层和Model层隔离开来
,起到了View层与Model层之间的解藕
的作用,View和Model将不在有联系。
.
View层的UI更新交于Activity,业务交于Presenter层,数据处理还是在Model层
.
MVP这样做的好处自然是模块的职责划分更清晰,提高了代码的维护性。
3. 在Android中如何实现标准的MVP设计架构?
- 需求假设:
- 2个EditView 分别可以输入 学生姓名,学生性别
- 1个Button 按压下去后,将EditView输入的内容作为新学生添加,并实时自动刷新展示学生总人数。
- 1个Button 按压下去后,手动刷新展示所有学生信息
Presenter层作为控制器和通信的桥梁,需同时持有V层和M层的对象,并只通过其对象实现的自身接口方法进行控制,不直接调用对象内定义的方法。
V层和M层自定义自己的接口并重写其接口内的方法,其接口内定义的方法作为向Presenter提供可以调用的方法。
.
.
作为创建的学生对象
/**
* 学生信息Bean
*/
public class StudentBean {
private String name;
private String gender;
public StudentBean(String name, String gender){
this.name = name;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
MainActivityView
public class MainActivityView extends AppCompatActivity implements MainActivityViewImpl {
private EditText vEdtName, vEdtGender;
private Button vBtnAdd,vBtnGetStudentInfo;
private TextView vTvDisplay,vTvDisplayListNumber;
//实例化StudentPresenter控制器
private StudentPresenter mStudentPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
addClickListener();
}
private void initView() {
mStudentPresenter = new StudentPresenter(this);
vEdtName = findViewById(R.id.vEdtName);
vEdtGender = findViewById(R.id.vEdtGender);
vTvDisplay = findViewById(R.id.vTvDisplayStudentInfo);
vBtnAdd = findViewById(R.id.vBtnAdd);
vTvDisplayListNumber = findViewById(R.id.vTvDisplayListNumber);
vBtnGetStudentInfo = findViewById(R.id.vBtnGetStudentInfo);
}
private void addClickListener(){
vBtnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStudentPresenter.addStudent(); //响应用户点击按钮操作,通知Presenter做处理
}
});
vBtnGetStudentInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStudentPresenter.doRefreshListInfo();
}
});
}
@Override
public String getStudentName() {
return vEdtName.getText().toString().trim();
}
@Override
public String getStudentGender() {
return vEdtGender.getText().toString().trim();
}
@Override
public void updateView_allStudentInfo(String string) {
vTvDisplay.setText(string);
}
@Override
public void updateView_studentNumber(String string) {
vTvDisplayListNumber.setText(string);
}
//假如产品改需求,通过Toast弹窗的显示当前学生人数,
//那么我们只需要在V层实现的自身接口改就行了。
// @Override
// public void updateView_studentNumber(String string) {
// Toast.makeText(this,string,Toast.LENGTH_SHORT).show();
// }
}
MainActivityViewImpl
/**
* View层接口,在此定义并列出所有 V层 可以进行的操作
*/
public interface MainActivityViewImpl {
/**
* 获取学生姓名 (可以看作提供给 Presenter 调用的方法)
*/
String getStudentName();
/**
* 获取学生性别 (可以看作提供给 Presenter 调用的方法)
*/
String getStudentGender();
/**
* 手动更新View的UI-所有list学生信息
*/
void updateView_allStudentInfo(String string);
/**
* 自动更新View的UI-学生List数量
*/
void updateView_studentNumber(String string);
}
StudentModel
/**
* Model层,作为数据处理的层,通过实现StudentModelImpl里的方法,进行对应的数据操作
*/
public class StudentModel implements StudentModelImpl {
private List <StudentBean> mStudentList = new ArrayList<>();
/**
* 向P层提供方法,对从Presenter拿到的 name 和 gender 作为数据进行处理,操作为创建一个新的学生bean并储存至学生list中
* 处理完毕后,通过接口回调返回给P层状态
* @param name
* @param gender
*/
@Override
public void addStudent(String name, String gender, eventAddStudentCallBack studentCallBack) {
StudentBean studentBean = new StudentBean(name,gender);
mStudentList.add(studentBean);
studentCallBack.completed(mStudentList.size()); //回调返回给P层
}
/**
* 返回学生list
*/
@Override
public List getStudentList() {
return mStudentList;
}
}
StudentModelImpl
/**
* Model层接口,在此定义并列出所有 M层 可以进行的操作
*/
public interface StudentModelImpl {
/**
* 添加学生操作 - 回调
*/
interface eventAddStudentCallBack{
void completed(int listSize);
}
/**
* 添加学生操作,(可以看作提供给 Presenter 调用的方法)
* @param name
* @param gender
* @param studentCallBack
*/
void addStudent(String name, String gender,eventAddStudentCallBack studentCallBack);
/**
* 获取学生list,(可以看作提供给 Presenter 调用的方法)
*/
List getStudentList();
}
StudentModel
/**
* Presenter控制器负责逻辑分发,在View层(Activity与xml)收到的用户的操作指令后,将起转发给Model层处理
* Model层处理完毕后,返回结果到这里进行处理后,再告知View层进行UI更新。
*/
public class StudentPresenter{
//Activity对象,同时V层实现了自身的接口
private MainActivityView mainActivityView;
//Model对象,同时M对象实现了自身的接口
private StudentModel mStudentModel;
public StudentPresenter(MainActivityView activity){
mainActivityView = activity;
mStudentModel = new StudentModel();
}
/**
* 调用M层的接口对象,添加学生信息,并从回调结果更新V层的UI
*/
public void addStudent(){
String name = mainActivityView.getStudentName(); //从V层的接口方法获取输入的学生名字
String gender = mainActivityView.getStudentGender(); //从V层的接口方法获取输入的学生性别
//将数据 和 操作指令转发给M层做处理,M层处理结束后通过接口返回结果
mStudentModel.addStudent(name, gender, new StudentModelImpl.eventAddStudentCallBack() {
@Override
public void completed(int listSize) {
mainActivityView.updateView_studentNumber("当前人数: "+listSize);
}
});
}
/**
* 调用V层的接口对象,更新V层的UI
*/
public void doRefreshListInfo(){
List<StudentBean> list = mStudentModel.getStudentList();
String text = "";
for(int i=0; i<list.size(); i++){
String studentInfo = "\n"+"姓名:"+list.get(i).getName() +" 性别: "+ list.get(i).getGender()+"\n";
text = text + studentInfo;
}
mainActivityView.updateView_allStudentInfo(text);
}
}
4. 完成代码请看github
- MVP设计模式 Github项目地址: 点击跳转
5. Android技术生活交流
微信 ----- QQ
[1]* 百度文献