介绍
MVC设计模式大家都知道,Model、View、Controller三者形成一个环,优点是方便易懂,缺点是Model可以直接改变View,View也能直接改变Model,两者耦合性很高。
MVP就是来解耦View和Model的,让View和Model只通过Presenter相互改变,而两者不能改变对方。
关键就是让View、Model和Presenter实现接口,然后把View和Model接口放在Presenter里面,并让View或Model持有一个Presenter接口,通过调用Presenter接口的方法。
所以,View中就只有接口中方法的实现和一些初始化动作,Model里只有类似get/set方法和接口中方法的实现,所有的业务逻辑都是在Presenter中实现的。
public interface MyContract {
interface Model {
void onDataChanged(String id, String name);
}
interface View {
void updateView(String id, String name);
}
interface Presenter {
void onViewClick(String id, String name);
void sendNewData(String id, String name);
}
}
举例
下面是例子,MainActivity中点击一个控件,改变Student的属性,并且把日志打出来。
定义Model、View和Presenter接口
这里我又多了一步封装
思路就是:
点击View,View调用Presenter.onViewClick(),传参
而后Presenter调用Model.onDataChanged(),更新属性
之后Presenter调用自己的sendNewData(),把新的值传过去
然后Presenter调用View.updateView(),view打印日志。
定义三个接口的实现类
Model实现类--Student:
public class Student implements MyContract.Model {
private String id;
private String name;
//无参+带参构造方法+get/set+toString()
@Override
public void onDataChanged(String id, String name) {
this.id = id;
this.name = name;
}
}
Presenter实现类--MyPresenter
public class MyPresenter implements MyContract.Presenter {
private MyContract.Model student;
private MyContract.View view;
public MyPresenter(MyContract.View view) {
this.view = view;
student = new Student();
}
@Override
public void onViewClick(String id, String name) {
student.onDataChanged(id, name);
sendNewData(id, name);
}
@Override
public void sendNewData(String id, String name) {
view.updateView(id, name);
}
}
View实现类--MainActivity:
public class MainActivity extends Activity implements MyContract.View{
private ImageView mImage;
private MyContract.Presenter presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MyPresenter(this);
mImage = findViewById(R.id.bayern);
mImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.onViewClick("25", "托马斯穆勒");
}
});
}
@Override
public void updateView(String id, String name) {
Log.i("MainActivity2", "id:"+id+"--name:"+name);
}
}
可以看到,Activity的代码只有初始化和接口方法的实现,没有多余的部分
而Activty中接口对象presenter可以根据不同的需求实例化不同的Presenter实现类,从而执行不同的业务逻辑
运行结果
不出意外,点击图片,出来一个MainActivity2的日志。
总结
可以看到,MVP主要是应用了接口来实现的解耦。
在我的例子中,MainActivity里的Presenter属性被实例化成了MyPresenter对象,这完全可以根据不同的需求判断实例化成其他的接口实现类。
而MyPresenter里的Model属性被实例化成了Student对象,这里我觉得可以把MyPresenter设计成一个父类,Model属性留给子类去赋值成各种具体的实现类,从而实现解耦和多态。