什么是MVP?
M就是model数据层,就是承载数据的实体
V就是view界面层,就是展示数据的
P就是Presenter(百度翻译为提出者; 赠送者)就是从Model中获取数据并提供给View的层
我们来做一个及其简单的例子,就是模拟一个插入动作,插入成功,页面提示Toast插入成功
我们先来具体分析下,这里面哪些是m层v层p层?
我这个例子为了简单省事,并没有具体的p层处理数据的操作,这是虚拟了一个插入成功的结果返回,
p层是做什么呢?p层就是沟通数据、界面的桥梁,就是我p层去处理数据的增删改查,然后就提供给v层去展示即可
public boolean insertData(){
return true;
}
public void notifyUpdateUI(){
if (activityImpl != null) {
if (insertData() == true)
activityImpl.showToast("插入成功");
}
}
以上就是p层2个简单的方法,一个是插入动作,插入成功返回一个结果值
然后p层的业务方法到此就做完了?
那问题来了,我们怎么样才去通知MainActivity界面去更新ui或者提示用户Toast显示插入成功呢?
其实这个就方法太多了,我们可以发送广播、EventBus、Handler传递都可以
但是呢?广播太费劲了,先抛开性能不说,就配置,注册也是不可取的,EventBus?也得需要jar,注册接受,Handler?其实也可以,呵呵,只不过我们是在做所谓的MVP分层,那么就用接口把,这个大家肯定都想到了
对!没错!我们需要一个接口,对于接口的深刻理解,这里不在做详细解释,因为我也没有深刻理解接口模式,我只能说自己会用,但是里面的深刻内涵,我目前无法深刻理解
那我们就来定义一个接口把?接口做什么呢?就是插入成功后,在P层放入一个接口方法
package com.example.mvpdemo;
public class Presenter {
ActivityImpl activityImpl;
public Presenter(ActivityImpl activityImpl) {
super();
this.activityImpl = activityImpl;
}
public boolean insertData(){
return true;
}
public void notifyUpdateUI(){
if (activityImpl != null) {
if (insertData() == true) {
activityImpl.showToast("插入成功");
}
}
}
}
干脆索性将P层的代码,全部贴出来,我们是通过构造器的方式传入
然后在MainActivity里面
package com.example.mvpdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements ActivityImpl,
OnClickListener {
Button mButton;
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.mButton);
mButton.setOnClickListener(this);
presenter = new Presenter(this);
}
/**
* p层处理完数据,进行回调接口实现
*/
@Override
public void showToast(String toastMessage) {
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show();
}
/**
* 点击去弹出toast
*/
@Override
public void onClick(View v) {
if (v.getId() == R.id.mButton) {
presenter.insertData();
presenter.notifyUpdateUI();
}
}
}
showToast方法中进行回调即可
我们来分析下
MainActivity实现一个ActivityImpl,本质上就是它拥有了一个自己全新定义的一个方法
void showToast(String toastMessage);
然后在P层持有MainActivity类的引用,这里是用到了多态,不再细细的讲解
presenter = new Presenter(this);
ActivityImpl activityImpl;
public Presenter(ActivityImpl activityImpl) {
super();
this.activityImpl = activityImpl;
}
调用p层的notifyUpdateUI方法也就是调用了MainActivity的方法
其实可以将P层看作一个代理类
那我们就改改上面的方式,来做进一步的理解;
我们就用一种静态代理模式来理解这个例子
关于静态、动态代理去看我下面的文章
我们可以这样理解,就是让P层成为一个代理类,然后P层V层,同时实现接口方法,在P层中持有V层的引用,P层插入成功后,调用P层的显示Toast方法,本质上是去调用V层的方法
看看我们稍加修改的P层代码
package com.example.mvpdemo;
public class Presenter implements ActivityImpl{
ActivityImpl activityImpl;
public Presenter(ActivityImpl activityImpl) {
super();
this.activityImpl = activityImpl;
}
public boolean insertData(){
return true;
}
@Override
public void showToast(String toastMessage) {
if (activityImpl != null) {
activityImpl.showToast(toastMessage);
}
}
}
如下是V层代码
package com.example.mvpdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements ActivityImpl,
OnClickListener {
Button mButton;
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.mButton);
mButton.setOnClickListener(this);
presenter = new Presenter(this);
}
/**
* p层处理完数据,进行回调接口实现
*/
@Override
public void showToast(String toastMessage) {
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show();
}
/**
* 点击去弹出toast
*/
@Override
public void onClick(View v) {
if (v.getId() == R.id.mButton) {
boolean insertData = presenter.insertData();
if (insertData) {
presenter.showToast("插入成功");
}
}
}
}
这样做是不是就更体现了MVP的一种静态代理思想
MVP经典的分层结构代码如下:
Model
package com.example.mvpdemo;
public class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Model(String name) {
super();
this.name = name;
}
public Model() {
super();
// TODO Auto-generated constructor stub
}
}
Presenter
package com.example.mvpdemo;
public class Presenter {
ActivityImpl activityImpl;
public Presenter(ActivityImpl activityImpl) {
super();
this.activityImpl = activityImpl;
}
public boolean insertData(){
return true;
}
public void notifyUpdateUI(){
if (activityImpl != null) {
if (insertData() == true) {
activityImpl.showToast("插入成功");
}
}
}
}
ActivityImpl
package com.example.mvpdemo;
public interface ActivityImpl {
void showToast(String toastMessage);
}
MainActivity
package com.example.mvpdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements ActivityImpl,
OnClickListener {
Button mButton;
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.mButton);
mButton.setOnClickListener(this);
presenter = new Presenter(this);
}
/**
* p层处理完数据,进行回调接口实现
*/
@Override
public void showToast(String toastMessage) {
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show();
}
/**
* 点击去弹出toast
*/
@Override
public void onClick(View v) {
if (v.getId() == R.id.mButton) {
presenter.insertData();
presenter.notifyUpdateUI();
}
}
}
代理模式的MVP代码如下
Model
package com.example.mvpdemo;
public class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Model(String name) {
super();
this.name = name;
}
public Model() {
super();
// TODO Auto-generated constructor stub
}
}
Presenter
package com.example.mvpdemo;
public class Presenter implements ActivityImpl{
ActivityImpl activityImpl;
public Presenter(ActivityImpl activityImpl) {
super();
this.activityImpl = activityImpl;
}
public boolean insertData(){
return true;
}
@Override
public void showToast(String toastMessage) {
if (activityImpl != null) {
activityImpl.showToast(toastMessage);
}
}
}
ActivityImpl
package com.example.mvpdemo;
public interface ActivityImpl {
void showToast(String toastMessage);
}
MainActivity
package com.example.mvpdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements ActivityImpl,
OnClickListener {
Button mButton;
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.mButton);
mButton.setOnClickListener(this);
presenter = new Presenter(this);
}
/**
* p层处理完数据,进行回调接口实现
*/
@Override
public void showToast(String toastMessage) {
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show();
}
/**
* 点击去弹出toast
*/
@Override
public void onClick(View v) {
if (v.getId() == R.id.mButton) {
boolean insertData = presenter.insertData();
if (insertData) {
presenter.showToast("插入成功");
}
}
}
}