【Android 架构之MVP】简单的MVP搭建(上)

一、为什么使用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);
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值