java-mvp模式简单实现

MVP模式

Presenter负责逻辑的处理,Model提供数据,View负责显示。

MVPView并不直接使用Model,它们之间的通信是通过Presenter(MVC中的Controller)来进行的,所有的交互都发生在Presenter内部.分离显示层和逻辑层,他们之间通过接口进行通信,降低耦合

而在MVCView会直接从Model中读取数据而不是通过Controller。在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。

MVP模式

MVC模式


Model

模型这一层之中做的工作是具体业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就明显需要实现一个Interface来松耦合了。

View

视图层负责显示数据、提供友好界面跟用户交互就行。MVPActivityFragment体现在了这一 层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。

Presenter

Presenter这一层处理着程序各种逻辑的分发,收到ViewUI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由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不用亲自去药店也能吃到药了(~ ̄▽ ̄)~




版权声明:本文为linsawako原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。