一、概述

MVP设计模式的前身是MVC,这个无需再议

在安卓工程中MVC对应关系如下:

Layout->View : 对应布局文件
Activity->Controller,View (其中activity分的并不是特别清楚)
各种业务逻辑实体类->Model

MVP的基本概念是:

MVP 指的是Model,View,Presenter(交互器/表示器),是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

二、MVP和MVC的区别

MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

给个图最能提现区别:

android Mvvm 用户控件做逻辑_mvp

图的上半部分是MVP模式 – 可以看出 View 和Model 并不直接交互, 而是通过presenter作为中间人去 协调工作。这么做的好处是使得代码更加清晰明了,分工明确。

图的下半部分是MVC模式 – 控制器controller(Activity)直接操作了 view 以及Model,也就是说运行View 和Model直接通信了。

总结MVP和MVC的优缺点如下:

1:MVC允许 View 和 Model 直接通讯。
2:MVP 中,View和 Model 的交互都在Presenter 内部来完成
3:MVP 中,View 通常会抽象化出来一系列的接口。(面向接口编程)
4:MVP 相对于 MVC 而言,大大降低了耦合度(Activity 不再进行复杂的操作),层级更明显,更利于单元测试。
5:MVP 的缺点:类文件会爆炸(极具增加),有一定的学习成本。

三、MVP的设计原则 – 怎么实现一个MVP设计模式?

1:一个 Activity对应一个 View (把activity当成MPV的view进行操作)
2:通常情况下,一个 View对应一个 Presenter,在业务复杂时,一个 View可对应多个 Presenter.
3.通常情况下将 View 与 Presenter抽象成接口。

四、例子

android Mvvm 用户控件做逻辑_mvp_02

MVP的 presenter 定义了业务逻辑实现, 它其实有 Model 和 View 交互完成的业务逻辑

然后在MainActivity中显示页面结果

**
 * MVP 中的Activity 其实就相当于 页面 用来显示最终结果的
 *
 * 它直接 根据布局 控件 来操作 布局属性
 */
public class MainActivity extends AppCompatActivity implements UserView{

    private Toolbar toolbar;
    private ClearEditText etUserName;
    private ClearEditText etPassword;
    private Button btn;
    private TextView tvResult;

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

        userPresenter = new UserPresenterImp(this);

        initialize();
        setSupportActionBar(toolbar);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //模拟网络延迟登陆
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        userPresenter.login();
                    }
                },500);

            }
        });
    }

    @Override
    public String getUserName() {
        return etUserName.getText().toString();
    }

    @Override
    public String getUserPwd() {
        return etPassword.getText().toString();
    }

    @Override
    public void onSuccess(UserBean userBean) {
        tvResult.setText(userBean.address);
    }

    @Override
    public void onError() {
        Toast.makeText(this,"用户名或者密码错误",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUserNameError() {
        etUserName.setError("用户名不能为空");//这个onError是在EditText窗口显示的
    }

    @Override
    public void onUserPwdError() {
        etPassword.setError("密码不能为空");
    }

    private void initialize() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        etUserName = (ClearEditText) findViewById(R.id.etUserName);
        etPassword = (ClearEditText) findViewById(R.id.etPassword);
        btn = (Button) findViewById(R.id.btn);
        tvResult = (TextView) findViewById(R.id.tvResult);
    }
}
public class UserPresenterImp implements UserPresenter {
    private UserView userView;
    public UserPresenterImp(UserView userView){
        this.userView = userView;
    }

    @Override
    public void login() {
        String username = userView.getUserName();
        String password = userView.getUserPwd();
        if(TextUtils.isEmpty(username)){
            userView.onUserNameError();
            return;
        }
        if(TextUtils.isEmpty(password)){
            userView.onUserPwdError();
            return;
        }
        if("123".equals(username)&&"aaa".equals(password)){
            String result = "{\n" +
                    "    \"username\": \"zccq\",\n" +
                    "    \"password\": \"1\",\n" +
                    "    \"address\": \"中国\"\n" +
                    "}";
            UserBean userBean = new Gson().fromJson(result, UserBean.class);
            userView.onSuccess(userBean);
        }else{
            userView.onError();
        }
    }
}

运行结果图:

android Mvvm 用户控件做逻辑_MVC_03