Android MVP模式思想

前言

MVP模式只是一个思想,并没有具体的,标准的编码规定。只要掌握了核心的思想,那么万变不离其宗。MVP模式,无法讲究的是单向通信,V单向和P通信,P单向和M通信,这便是MVP的精髓。

预备知识

  • 面向接口的编程思想
  • 向上转型的概念
  • 解耦

面向接口编程

先复习一下接口的概念:

在Java程序设计语言中,接口不是类,而是对希望符合这个接口的类的一组需求(出自《Java核心卷一》p222页)

说白了,接口就是一组需求

而面向接口编程呢,就是在开始开发前,先定义好接口(可以理解为先列出一组需求),然后再进行开发

向上转型

父类引用指向子类对象(即多态),看完下面的代码应该更好理解些

public interface IStudent {
    String getName();
}
public class Student implements IStudent{//此时IStudent是父类,Student是子类
    @Override
    public String getName() {
        return "任我行";
    }
}
public class Test {
    public static void main(String[] args) {
        IStudent iStudent;
        iStudent=new Student();//父类引用指向子类的对象,这里做了向上转型
        System.out.println("学生的名字是:"+iStudent.getName());//打印结果:学生的名字是:任我行
    }
}

解耦

解耦即降低依赖性

MVP模式

Actually,我觉得MVP模式的灵魂就是presenter层同时持有view层和model层的引用(请联系上边的向上转型的概念)。


照此逻辑,我们简单实现一个常见的登录模块。根据面向接口编程,我们首先列出我们的接口(需求):

/**
 * View层的需求
 */
public interface IView {
    //1. 获取用户的输入信息
    public User getViewUser();
    //2. 登录成功的操作
    public void loginSuceess();
    //3. 登录失败后的操作
    public void loginFail();
}

xx

/**
 * Model层的需求
 */
public interface IModel {
     //判断信息是否正确
     public boolean isOk(User user);
}
/**
 * presenter层的需求
 */
public interface IPresenter {
    //登录操作
    public void login();
}

好了,接口写完,现在去实现接口:

public class View extends AppCompatActivity implements IView{
    private EditText mUsername;
    private EditText mPassword;
    private Button mButton;

    private IPresenter iPresenter;//present的引用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mUsername = findViewById(R.id.et_username);
        mPassword = findViewById(R.id.et_password);
        mButton = findViewById(R.id.btn_login);

        iPresenter = new Presenter(this);//父类引用指向子类对象,向上转型,这个this指向的是View本身,也就是是传入了一个IView的子类对象
        //此时Presenter同时持有Model层和View层的对象
        mButton.setOnClickListener(new android.view.View.OnClickListener() {
            @Override
            public void onClick(android.view.View v) {
                iPresenter.login();//此操作会执行Pressenter对象的login方法
            }
        });
    }

    //实现IView的需求
    @Override
    public User getViewUser() {
        return new User(mUsername.getText().toString(),mPassword.getText().toString());
    }

    @Override
    public void loginSuceess() {
        Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void loginFail() {
        Toast.makeText(this, "登录失败!", Toast.LENGTH_SHORT).show();
    }
}
public class Model implements IModel{
    //IModel的需求
    @Override
    public boolean isOk(User user) {
        if (user.getUsername().equals("root")&&user.getPassword().equals("123")){
            return true;
        }
        return false;
    }
}

我觉得mvp模式的核心在此

//presenter层,联系model和view的枢纽
public class Presenter implements IPresenter {
    private IModel iModel;
    private IView iView;

    public Presenter(IView iView) {
        this.iModel = new Model();//向上转型
        this.iView = iView;//向上转型
    }

    //IPresenter的需求
    @Override
    public void login() {//当View层点击button的时候,将会调用到这个方法
        if (iModel.isOk(iView.getViewUser())){
            iView.loginSuceess();//执行view层的loginSuceess
        }else {
            iView.loginFail();//执行view层的loginFail
        }
    }
}

model,view,presenter的接口,就像是三条引子,把它们联系在了一起

参考资料

肥肠感谢这些参考资料的作者(≧∀≦)ゞ(重点推荐第一篇,讲的太好了)