MVC-MVP

作者: 吃茶泡饭丶 | 来源:发表于2018-11-27 09:40 被阅读0次

    任何架构的设计目的都是为了:低耦合,高复用,易测试,好维护。

    MVC

    MVC(Model View Controller),是软件架构中最常见的一种框架,简单来说就是通过Controller的控制去操作Model的数据,并返回给View展示。


    MVC.png

    View层一般采用XMl文件进行界面的描述;
    Module则对应本地数据文件或者网络获取的数据体;
    Controller部分则由Activity承担;
    这个框架并非我们自己完成的,而是由framework给我们搭建好并提供给我们。

    setContentView的作用???

    在Android中MVC并不完美,View既依赖于Controller又依赖于Model,View同时含有Controller与Model的引用;UI逻辑同时存在于View与Model之间导致业务逻辑与UI逻辑无法分离,在修改UI逻辑时, 也需要修改Model, 降低了架构的灵活性,增加模块耦合, 影响重构。

    MVP

    MVP作为MVC的演化,解除了View和Module的耦合,同时又带来了良好的可扩展性,可测试性。对于Android来说,MVP的Model层相对于MVC是一样的,而activity/fragment不再是Controller层,而是纯粹的view层,所有关于用户事件的转发全部交由Presenter层处理。
    MVP与MVC最大的区别在于Model与View之间的交互由Presenter完成而Presenter与View之间的交互是通过接口的方式。
    Google官方相关MVP样例
    来自官网的架构图

    mvp.png
    图中除了Activity/Fragment的黄色部分外都算是Model数据层,REPOSITORY是用来管理数据存储的,Remote data source和Local data source分别代表远程(网络)和本地(SQL)的数据来源。

    以登录为例
    按照MVP的思路:
    这里我创建了一个CallBack,在Callback中定义数据请求的各种反馈状态,方便Model层向Presenter层反馈请求信息。

    /**
     * @Author: chichapaofan
     * @CreateDate: 2018/11/1
     * @Description: 请求结果
     */
    public interface CallBack {
    
        /**
         * 请求成功
         *
         * @param date
         */
        void onSuccess(String date);
    
        /**
         * 请求成功,无法正常返回数据
         *
         * @param msg
         */
        void onFailure(String msg);
    
        /**
         * 请求数据失败
         */
        void onError();
    
        /**
         * 请求结束,无论成功失败
         */
        void onFinish();
    }
    

    Model
    在Model类中进行具体的网络请求操作。通过判断请求的参数反馈不同的请求状态。

    /**
     * @Author: chichapaofan
     * @CreateDate: 2018/11/1
     * @Description: Model层
     */
    public class LoginModel {
    
        /**
         * 获取数据
         *
         * @param param
         * @param callBack
         */
        public static void getData(final String param, final CallBack callBack) {
            //模拟网络请求
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (param.equals("normal")) {
                        callBack.onSuccess("参数:" + param + "/请求结果:网络数据成功");
                    } else if (param.equals("failure")) {
                        callBack.onFailure("参数:" + param + "/请求结果:参数有误");
                    } else if (param.equals("error")) {
                        callBack.onError();
                    }
                    callBack.onFinish();
                }
            }, 3000);
        }
    }
    

    View
    View接口的作用是根据具体业务的需要,为Presenter提供调用Activity中具体UI逻辑操作的方法。

    /**
     * @Author: chichapaofan
     * @CreateDate: 2018/11/1
     * @Description:View层
     */
    public interface LoginView {
    
        /**
         * 显示正在加载进度框
         */
        void showLoading();
    
        /**
         * 隐藏正在加载进度框
         */
        void hideLoading();
    
        /**
         * 请求成功展示数据
         */
        void showData(String data);
    
        /**
         * 展示失败信息
         */
        void showFailureMessage(String msg);
    
        /**
         * 数据请求异常调用此接口
         */
        void showError();
    }
    

    Presenter
    Presenter类是具体的逻辑业务处理类,负责请求数据,处理数据请求的反馈。
    为了能够通过View接口通知Activity进行更新界面等操作,需要在Presenter类的构造方法中传递一个View接口的参数。

    /**
     * @Author: chichapaofan
     * @CreateDate: 2018/11/1
     * @Description:Persenter层
     */
    public class LoginPresenter {
    
        private LoginView loginView;
    
        public LoginPresenter(LoginView loginView) {
            this.loginView = loginView;
        }
    
        public void getData(String param) {
            //展示加载
            loginView.showLoading();
            LoginModel.getData(param, new CallBack() {
                @Override
                public void onSuccess(String date) {
                    loginView.showData(date);
                }
    
                @Override
                public void onFailure(String msg) {
                    loginView.showFailureMessage(msg);
                }
    
                @Override
                public void onError() {
                    loginView.showError();
                }
    
                @Override
                public void onFinish() {
                    loginView.hideLoading();
                }
            });
        }
    }
    

    在Activity中
    在Activity代码中如果想要调用Presenter就要先实现Presenter需要的View接口。

    public class LoginActivity extends AppCompatActivity implements LoginView {
    
        private LoginPresenter loginPresenter;
    
        private AutoCompleteTextView mEmailView;
        private EditText mPasswordView;
        private View mProgressView;
        private View mLoginFormView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login2);
            mEmailView = findViewById(R.id.email);
            mPasswordView = findViewById(R.id.password);
            mProgressView = findViewById(R.id.login_progress);
            mLoginFormView = findViewById(R.id.email_sign_in_button);
            
            //
            loginPresenter=new LoginPresenter(this);
    
            mLoginFormView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //
                    if(mEmailView.getText().toString().equals("normal")){
                        loginPresenter.getData("normal");
                    }else if(mEmailView.getText().toString().equals("failure")){
                        loginPresenter.getData("failure");
                    }else if(mEmailView.getText().toString().equals("error")){
                        loginPresenter.getData("error");
                    }
                }
            });
        }
    
        @Override
        public void showLoading() {
            mProgressView.setVisibility(View.VISIBLE);
        }
    
        @Override
        public void hideLoading() {
            mProgressView.setVisibility(View.INVISIBLE);
        }
    
        @Override
        public void showData(String data) {
            Toast.makeText(this, data, Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void showFailureMessage(String msg) {
            Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void showError() {
            Toast.makeText(this, "服务器开小差惹", Toast.LENGTH_SHORT).show();
        }
    }
    

    到此简单的MVP架构实现完成!!

    相关文章

      网友评论

          本文标题:MVC-MVP

          本文链接:https://www.haomeiwen.com/subject/mmjftqtx.html