MVP(Model View Presenter)
作为MVC的演化,解决了MVC不少的缺点,对于Android来说,MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。
下面还是让我们看图:
从图中就可以看出,最明显的差别就是view层和model层不再相互可知,完全的解耦,取而代之的presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。看到这里大家可能会问,虽然view层和model层解耦了,但是view层和presenter层不是耦合在一起了吗?其实不是的,对于view层和presenter层的通信,我们是可以通过接口实现的;具体的意思就是说我们的activity,fragment可以去实现实现定义好的接口,而在对应的presenter中通过接口调用方法。不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。
注意:其实最好的方式是使用fragment作为view层,而activity则是用于创建view层(fragment)和presenter层(presenter)的一个控制器。
MVP设计执行的基本流程:
首先视图接受用户输入请求,然后将请求传递给Presenter,Presenter再调用某个模型来处理用户的请求,模型中修改数据后传递更新数据到Presenter中,Presenter再将处理后的结果交给视图进行格式化输出给用户。
MVP的实践
例子来自:https://blog.csdn.net/qq_30379689/article/details/52910567
我们采用ListView来演示我们的MVP模式,目录结构:
实体类:包含了学生的名字和图片信息
public class Student {
//学生的名字
private String name;
//学生的图片信息
private int image;
public Student(String name, int image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
模型类(Model层),模型类分为两个类:
1、模型抽象类:对模型的方法的抽象,方便阅读该模型层有哪些功能,类似于说明书
2、模型实现类:通常是对本地数据库的操作或者是通过网络请求获取网络数据的操作
我们在Model里面模拟了一个本地数据库,并提供了增删改查的方法
/**
* 作者:许英俊
* 模型抽象类
* 对模型层的抽象
*/
public interface IStudentMode {
/**
* 查询所有学生
* @param listener
*/
void query(onQueryListener listener);
/**
* 添加学生
* @param listener
*/
void addStudent(onAddStudentListener listener);
/**
* 删除学生
* @param listener
*/
void deleteStudent(onDeleteStudentListener listener);
/**
* 查询学生回调
*/
interface onQueryListener{
void onComplete(List<Student> students);
}
/**
* 添加学生回调
*/
interface onAddStudentListener{
void onComplete();
}
/**
* 删除学生回调
*/
interface onDeleteStudentListener{
void onComplete();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
/**
* 作者:许英俊
* 模型实现类
* 对模型层的实现
*/
public class StudentMode implements IStudentMode {
private static List<Student> list = new ArrayList<>();
/**
* 本地模拟数据库
*/
static {
list.add(new Student("小龙", R.drawable.man));
list.add(new Student("小红", R.drawable.woman));
list.add(new Student("小龙", R.drawable.man));
}
/**
* 查询学生
* @param listener
*/
@Override
public void query(onQueryListener listener) {
if (listener != null) {
listener.onComplete(list);
}
}
/**
* 添加学生
* @param listener
*/
@Override
public void addStudent(onAddStudentListener listener) {
list.add(new Student("小燕", R.drawable.girl));
if (listener != null) {
listener.onComplete();
}
}
/**
* 删除学生
* @param listener
*/
@Override
public void deleteStudent(onDeleteStudentListener listener) {
if (list.size() > 0) {
list.remove(list.size() - 1);
}
if (listener != null) {
listener.onComplete();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
视图类(View层):对视图的方法的抽象,方便阅读该视图层有哪些功能,类似于说明书
/**
* 作者:许英俊
* 视图类
* 对视图方法的抽象
*/
public interface IStudentView {
/**
* 展示学生
* @param list
*/
void showStudent(List<Student> list);
/**
* 刷新学生
*/
void refreshStudent();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
中间者(Presenter):绑定Model层和View层,操作Model数据,并在View更新
/**
* 作者:许英俊
* 中间者
* 绑定View层和Model层
*/
public class StudentPresenter {
private IStudentMode studentMode;
private IStudentView studentView;
public StudentPresenter(IStudentView studentView) {
studentMode = new StudentMode();
this.studentView = studentView;
}
/**
* 通过Model查询学生,在View中展示
*/
public void queryStudent(){
studentMode.query(new IStudentMode.onQueryListener() {
@Override
public void onComplete(List<Student> students) {
studentView.showStudent(students);
}
});
}
/**
* 通过Model添加学生,在View中更新
*/
public void addStudent(){
studentMode.addStudent(new IStudentMode.onAddStudentListener() {
@Override
public void onComplete() {
studentView.refreshStudent();
}
});
}
/**
* 通过Model删除学生,在View中更新
*/
public void deleteStudent(){
studentMode.deleteStudent(new IStudentMode.onDeleteStudentListener() {
@Override
public void onComplete() {
studentView.refreshStudent();
}
});
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
视图类:Activity类中,实现我们的视图抽象类,并使用Presenter的方法
/**
* 作者:许英俊
* 视图类
* 对视图抽象类的实现
*/
public class StudentActivity extends AppCompatActivity implements IStudentView, View.OnClickListener {
private ListView lv;
private StudentAdapter adapter;
private Button bt_add, bt_delete;
private StudentPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student);
lv = (ListView) findViewById(R.id.lv);
bt_add = (Button) findViewById(R.id.bt_add);
bt_delete = (Button) findViewById(R.id.bt_delete);
bt_add.setOnClickListener(this);
bt_delete.setOnClickListener(this);
//中间者类
presenter = new StudentPresenter(this);
//查询学生
presenter.queryStudent();
}
/**
* 展示学生
* @param list
*/
@Override
public void showStudent(List<Student> list) {
adapter = new StudentAdapter(this, list);
lv.setAdapter(adapter);
}
/**
* 刷新学生界面
*/
@Override
public void refreshStudent() {
adapter.notifyDataSetChanged();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//添加学生
case R.id.bt_add:
presenter.addStudent();
break;
//删除学生
case R.id.bt_delete:
presenter.deleteStudent();
break;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
效果图
进阶
mvp的设计模式,mvp模式是mvc的进化版,它让view和controllor充分分离开来来了,presenter作为桥梁,持有view和model的引用,当用户触发操作时,会去调用presenter,presenter去操作model,model刷新数据后回调给presenter在回调给view刷新UI,这样就让逻辑很清楚,代码耦合性降低,但是同样也是类比之前多了很多,对于mvp的封装和介绍,推荐你们看下网上的这三篇文章:
Android MVP升级路(一)乞丐版的自我救赎:https://www.jianshu.com/p/5c3bc32afa36
Android MVP升级路(二)轻项目标配时尚版:https://www.jianshu.com/p/d24f9856f97d
Android MVP升级路(三)随心所欲的旗舰版:https://www.jianshu.com/p/f4f3c732cbcf