MVP模式
Presenter负责逻辑的处理,Model提供数据,View负责显示。
在MVP中View并不直接使用Model,它们之间的通信是通过Presenter(MVC中的Controller)来进行的,所有的交互都发生在Presenter内部.分离显示层和逻辑层,他们之间通过接口进行通信,降低耦合
而在MVC中View会直接从Model中读取数据而不是通过Controller。在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。
MVP模式
MVC模式
Model
模型这一层之中做的工作是具体业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就明显需要实现一个Interface来松耦合了。
View
视图层负责显示数据、提供友好界面跟用户交互就行。MVP下Activity和Fragment体现在了这一 层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。
Presenter
Presenter这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。
上一次向人讲解MVP后,他问我“是不是相当于,我生病了,但是我不会去医院,然后让我妈带我去”,我当时回答说是对的...orz,但现在想起来这个说法其实忽略了MVP模式的一个关键作用,Presenter完全把Model和View进行了分离。
现在使用这个例子来进行说明
先定义基础的接口
public interface BaseModel {
//...
}
public interface BasePresenter {
//...
}
public interface BaseView<T> {
void setPresenter(T presenter);
}定义一个Contract的接口,Presenter,View,Model继承自基础的接口并进行拓展
public interface SickContract {
interface Presenter extends BasePresenter{
void toPharmacy(String symptom);//去药店
}
interface View extends BaseView<Presenter>{
void eatMedicine(Medicine medicine);//吃药
}
interface Model extends BaseModel{
Medicine giveMedicine(String symptom);//给药
}
}先来定义一个Medicine的类,它有数据域name
public class Medicine {
private String name;
public Medicine(String name) {
this.name = name;
}
@Override
public String toString() {
return "Medicine: " + name;
}
}定义一个Child类(View层),它有一个Mother类(presenter层)的引用,可以调用presenter的方法,并将自己的引用传递给Presenter层
public class Child implements SickContract.View{
private SickContract.Presenter presenter;
public Child() {
setPresenter(new Mother(this));
}
public void getSick(String symptom){
System.out.println("小孩:我生病了!症状是:" + symptom + " 妈妈帮我去买药吧");
presenter.toPharmacy(symptom);//调用presenter的方法,让妈妈去药店
}
@Override
public void setPresenter(Presenter presenter) {
this.presenter = presenter;
}
@Override
public void eatMedicine(Medicine medicine) {
System.out.println("吃药 " + medicine);
System.out.println("病好了");
}
}定义Mother类(Presenter层),它有一个Child(View层)的引用,和一个Pharmacy(Model层)的引用,它可以得到Model返回的数据并调用View层的方法进行视图更新。
public class Mother implements SickContract.Presenter{
private SickContract.View view;
private SickContract.Model model;
public Mother(SickContract.View view) {
this.view = view;
model = new Pharmacy();
}
@Override
public void toPharmacy(String symptom) {
System.out.println("妈妈:好的,我去帮你买药");
Medicine medicine = model.giveMedicine(symptom);//得到药店给的药
System.out.println("药买到了,吃吧");
view.eatMedicine(medicine);//让小孩吃药
}
}
定义Pharmacy(Model层),作用是返回数据给逻辑层
public class Pharmacy implements SickContract.Model{
@Override
public Medicine giveMedicine(String symptom) {
if (symptom.equals("感冒")) {
System.out.println("药店:感冒了是吧,给你感冒药");
Medicine medicine = new Medicine("感冒药");
return medicine;
}
return null;
}
}现在来测试一下吧
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.getSick("感冒");
}
}输出:
小孩:我生病了!症状是:感冒 妈妈帮我去买药吧
妈妈:好的,我去帮你买药
药店:感冒了是吧,给你感冒药
药买到了,吃吧
吃药 Medicine: 感冒药
病好了Child不用亲自去药店也能吃到药了(~ ̄▽ ̄)~