一、为什么使用MVP?
1. MVC传统模式架构的劣势
M层:数据层->包含(数据库、文件、网络、Javabean等等…)
V层:UI层->包含(View以及子类、Fragment以及子类、Activity以及子类)
C层:中介->作用(目的:就是将UI层和数据层进行解耦和,同时进行关联)
我们在安卓中使用最多的就是MVC,相对来说他要求的技术难点较低,好写,尤其是view层和control,安卓自身就已经做了一定的拆分。
缺点:
视图层(V层)和 逻辑层(C层)依然拆分不彻底,耦合性还是高,不利于维护、阅读、迭代。
使用MVC的框架列举:
Android基于MVC的设计模式 , 百度地图基于MVC的架构 等
Android基于MVC的设计模式:
View层:xml ,
C 层:Actvity ,
M层:一个类中。
关于MVC各层之间关系所对应的设计模式
View层,单独实现了组合模式
Model层和View层,实现了观察者模式
View层和Controller层,实现了策咯模式
2. 中介者设计模式
其实大家会发现这个统计部门很类似于中介 ,统计部门使得这些对象不必相互明显作用。从而使它们可以降低耦合(松散耦合)。
当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立变化。中介者模式将多对多的相互作用转化为一对多的相互作用。中介者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
简单来说 : 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介者模式-应用场景?
.
当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其他对象的行为,可以采用中介者模式来解决紧耦合问题。
.如果还是对于中介者模式不了解,可以下载下面的代码看一下
中介者模式代码 Demo下载
3. MVP中模块拆分化思想的优势
Model:数据层. 负责与网络层和数据库层的逻辑交互.
View :UI层. 显示数据, 并向Presenter报告用户行为.
Presenter:从Model拿数据, 应用到UI层, 管理UI的状态, 决定要显示什么, 响应用户的行为.
M层:数据层 --> 包含(数据库、文件、网络、Javabean等等…)
V层:UI层 --> 包含(View以及子类、Fragment以及子类、Activity以及子类)
P层:中介 --> 作用(目的:就是将UI层和数据层进行解耦和,同时进行关联)
MVP设计目的:为了将UI层和数据层进行分离
MVP模式的最主要优势就是耦合降低, Presenter变为纯Java的代码逻辑, 不再与Android Framework中的类,如Activity, Fragment等关联, 便于写单元测试。
二、MVP的使用
1. MVP角色划分
抽象层
- M层 ===》MvpModel
- V层 ===》LoginView(UI交互接口)
- P层 ===》MvpPresenter
具体实现层
- M层 ===》LoginModel
- V层 ===》MainActivity(或者:Fragment)
- P层 ===》LoginPresenter
2. MVP代码案例
抽象层
- M层 ===》MvpModel
public abstract class MvpModel{
}
- V层 ===》LoginView(UI交互接口)
public interface LoginView{
void onLoginResult(String reslt);
}
- P层 ===》MvpPresenter
public abstract class MvpPresenter{
private LoginModel model;
private LoginView view;
public LoginView getView(){
return view;
}
//V层绑定的方法
public void attachView(LoginView view){
this.view = view;
}
//V层解绑的方法
public void detchView(){
this.view=null;
}
}
具体实现层
- M层 ===》LoginModel
public class LoginModel extends MvpModel{
public void login(String username,String password,
final HttpUtils.OnHttpResultListener listener){
Map<String,Object> params = new HashMap<>();
params.put("phone",username);
params.put("pwd",password);
new HttpTask.Builder()
.method("POST")
.url("http://172.17.8.100/small/user/v1/login")
.paramMap(params)
.onHttpResultListener(new HttpUtils.OnHttpResultListener(){
@Override
public void onResult(String result){
listener.onResult(result);
}
}).build().execute();
}
}
- P层 ===》LoginPresenter
public class LoginPresenter extends MvpPresenter{
private LoginModel model;
public LoginPresenter(){
this.model = new LoginModel();
}
public void login(String username,String password){
this.model.login(username,password,
new HttpUtils.OnHttpResultListener(){
@Override
public void onResult(String result){
if(getView()!=null){
getView().onLoginResult(result);
}
}
});
}
}
- V层 ===》MainActivity(或者:Fragment)
public class MainActivity extends AppCompatActivity
implements LoginView{
private LoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.presenter = new LoginPresenter();
//绑定View
this.presenter.attachView(this);
}
public void clickLogin(View view){
this.presenter.login("15001194794","123");
}
@Override
public void onLoginResult(String reslt){
Toast.makeText(MainActivity.this,reslt,
Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy(){
super.onDestroy();
presenter.detchView();
}
}
三、MVP复杂案例
1. 复杂MVP角色划分
接口层
- M层 ===》MvpModel
- V层 ===》MvpView
- P层 ===》MvpPresenter
抽象层
- M层 ===》BaseModel
- V层 ===》BaseActivity
- P层 ===》BasePresenter
具体实现层
- M层 ===》LoginModel
- V层 ===》LoginView、MainActivity(或者:Fragment)
- P层 ===》LoginPresenter
2. 复杂MVP代码案例
(1)接口层
- M层 ===》MvpModel
public interface MvpModel {
}
- V层 ===》MvpView
public interface MvpView {
}
- P层 ===》MvpPresenter
public interface MvpPresenter <V extends MvpView>{
//关联视图
void attachView(V view);
//分离视图
void detachView();
}
(2)抽象层
- M层 ===》BaseModel
public abstract class BaseModel implements MvpModel {
private Context context;
public BaseModel(Context context) {
this.context = context;
}
public Context getContext() {
return context;
}
}
- V层 ===》BaseActivity
public abstract class BaseActivity<V extends MvpView,
P extends MvpPresenter<V>> extends AppCompatActivity
implements MvpView {
private P presenter;
public abstract P createPersenter();
public P getPresenter() {
return presenter;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (presenter == null) {
this.presenter = createPersenter();
}
if (presenter != null) {
//关联视图
this.presenter.attachView((V) this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//分离视图
this.presenter.detachView();
}
}
- P层 ===》BasePresenter
public class BasePresenter <V extends MvpView> implements MvpPresenter<V> {
private V view;
public V getView(){
return view;
}
@Override
public void attachView(V view){
this.view = view;
}
@Override
public void detachView(){
this.view = null;
}
}
(3)具体实现层
- M层 ===》LoginModel
public class LoginModel extends BaseModel {
public LoginModel(Context context) {
super(context);
}
public void httpLogin(String username, String password,
final HttpUtils.OnHttpResultListener listener) {
//伪登录
if (username.equals("12345")&&password.equals("000")){
listener.onResult("登录成功");
return;
}
// 本地接口
// Map<String, Object> params = new HashMap<>();
// params.put("phone", username);
// params.put("pwd", password);
//
// new HttpTask.Builder()
// .method("POST")
// .url("http://172.17.8.100/small/user/v1/login")
// .paramMap(params)
// .onHttpResultListener(new HttpUtils.OnHttpResultListener() {
//
// @Override
// public void onResult(Object result) {
// listener.onResult(result);
// }
// }).build().execute();
}
}
- P层 ===》LoginPresenter
public class LoginPresenter extends BasePresenter<LoginView> {
private LoginModel model;
public LoginPresenter(Context mContext) {
this.model = new LoginModel(mContext);
}
public void login(String username, String password) {
this.model.httpLogin(username, password,
new HttpUtils.OnHttpResultListener() {
@Override
public void onResult(Object result) {
getView().onLogin((String) result);
}
});
}
}
- V层 ===》LoginView、MainActivity(或者:Fragment)
LoginView.java
public interface LoginView extends MvpView {
void onLogin(String result);
}
MainActivity.java
public class MainActivity extends BaseActivity<LoginView, LoginPresenter>
implements LoginView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getPresenter().login("12345", "000");
}
});
}
@Override
public void onLogin(String result) {
Toast.makeText(this, "返回内容:" + result, Toast.LENGTH_LONG).show();
}
@Override
public LoginPresenter createPersenter() {
return new LoginPresenter(this);
}
}