MVP:
View 对应于Activity,负责View的绘制以及与用户交互
Model 依然是业务逻辑和实体模型
Presenter 负责完成View于Model间的交互
在MVP模式里通常包含4个要素:
(1) View :负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2) View interface :需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3) Model :负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4) Presenter :作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
例子如下:
presenter接口
/**
* presenter接口
*/
public interface ILoginPresenter {
public void clear();
public void doLogin(String name, String password);
}
view接口
/**
* view接口
*/
public interface ILoginView {
public void onClearText();
public void onLoginResult(boolean result, int code);
}
model层
package com.example.administrator.myapplication;
/**
* model类
*/
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() {
}
public User(String password, String name) {
this.password = password;
this.name = name;
}
}
view层
MainActivity.java
package com.example.administrator.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/*
* * Presenter是用作Model和View之间交互的桥梁
*
* Presenter与View之间的交互是通过接口的
* */
public class MainActivity extends AppCompatActivity implements ILoginView {//实现view接口
private Button login;
private Button clear;
private EditText name;
private EditText pwd;
private ILoginPresenter loginPresenter;//activity中的presenter为全局变量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
login = (Button) findViewById(R.id.login);
clear = (Button) findViewById(R.id.clear);
name = (EditText) findViewById(R.id.name);
pwd = (EditText) findViewById(R.id.pwd);
loginPresenter = new LoginPresentercompl(this);//实例化LoginPresentercompl(继承自presenter)
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String na = name.getText().toString().trim();
String pass = pwd.getText().toString().trim();
loginPresenter.doLogin(na, pass);//presenter的方法
}
});
clear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loginPresenter.clear();//presenter的方法
}
});
}
//实现view接口的方法
@Override
public void onClearText() {
name.setText("");
pwd.setText("");
Toast.makeText(this, "清除", Toast.LENGTH_SHORT).show();
}
//实现view接口的方法
@Override
public void onLoginResult(boolean result, int code) {
if (result) {
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
}
}
}
presenter层
Presenter类
package com.example.administrator.myapplication;
/**
* Presenter是用作Model和View之间交互的桥梁
*
* Presenter与View之间的交互是通过接口的
*/
public class LoginPresentercompl implements ILoginPresenter {//presenter
private ILoginView view;//view的接口为全局变量
private User user;//model
public LoginPresentercompl(ILoginView view) {
this.view = view;
user = new User("123456", "张三");
}
@Override
public void clear() {
view.onClearText();
}
@Override
public void doLogin(String name, String password) {
boolean result = false;
int code = 0;
if (name.equals(user.getName()) && password.equals(user.getPassword())) {
result = true;
code = 1;
} else {
result = false;
code = 0;
}
view.onLoginResult(result, code);
}
}
XML布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清除"/>
</LinearLayout>
MVP与MVC的异同
MVC模式与MVP模式都作为用来分离UI层与业务层的一种开发模式被应用了很多年。在我们选择一种开发模式时,首先需要了解一下这种模式的利弊:
无论MVC或是MVP模式都不可避免地存在一个弊端:额外的代码复杂度及学习成本。
但比起他们的优点,这点弊端基本可以忽略了:
(1)降低耦合度
(2)模块职责划分明显
(3)利于测试驱动开发
(4)代码复用
(5)隐藏数据
(6)代码灵活性
对于MVP与MVC这两种模式,它们之间也有很大的差异。有一些程序员选择不使用任何一种模式,有一部分原因也许就是不能区分这两种模式差异。以下是这两种模式之间最关键的差异:
MVP模式:
M-Model-模型、V-View-视图、P-Presenter-表示器
1.View不直接与Model交互 ,而是通过与Presenter交互来与Model间接交互
2.Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
3.通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
MVC模式:
M-Model-模型、V-View-视图、C-Controller-控制器
1.View可以与Model直接交互
2.Controller是基于行为的,并且可以被多个View共享
3.可以负责决定显示哪个View
参考
浅谈安卓MVP模式