• Android之MVP设计模式


    一、概述

    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。

    给个图最能提现区别:

    图的上半部分是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抽象成接口。

    四、例子

    工程结构

    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 = "{ " + " "username": "zccq", " + " "password": "1", " + " "address": "中国" " + "}"; UserBean userBean = new Gson().fromJson(result, UserBean.class); userView.onSuccess(userBean); }else{ userView.onError(); } } }

    运行效果图:

    源码下载地址:https://yunpan.cn/cu7JQWCwLGLum (提取码:4195)

  • 相关阅读:
    Menu-actionBarMenu字体颜色修改
    actionBarTab-actionBarTab自定义 布局没法改变其中字体相对中间的位置
    Funui-overlay 如何添加theme 的 overlay
    java进阶——反射(Reflect)
    java工具类学习整理——集合
    Java实例练习——java实现自动生成长度为10以内的随机字符串(可用于生成随机密码)
    打通Java与MySQL的桥梁——jdbc
    SQL数据库操作整理
    PhpStorm 4.0 & 5.0 部署本地Web应用
    PhpStorm 4.0 & 5.0 部署本地Web应用
  • 原文地址:https://www.cnblogs.com/android-zcq/p/5126925.html
Copyright © 2020-2023  润新知