zoukankan      html  css  js  c++  java
  • Android中的MVP架构分解和实现

    1、概述

    传统的Android开发架构通常是MVC模式。

    • Model:业务逻辑和实体模型
    • View:相应于布局文件
    • Controllor:相应于Activity

    单独从逻辑看起来很好,与我们做Web开发时,开发模式相似,但在实际开发中。View相应于布局文件,实际上关于该布局文件里的数据绑定的操作,事件处理的代码都在Activity中,Activity既像View又像Controller(MVVP架构中包含数据绑定)。导致Activity中职责太重。耦合度大。改动和维护起来很麻烦。

    这里写图片描写叙述

    2、MVP介绍

    这里写图片描写叙述

    MVP架构中,View 相应于Activity,负责View的绘制以及与用户交互
    Model 依旧是业务逻辑和实体模型,Presenter 负责完毕View于Model间的交互。

    (1)Model层

    模型层之中做的工作是详细业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就须要实现一个Interface来松耦合了。

    (2)View层

    视图层体现的很轻薄。负责显示数据、提供友好界面跟用户交互即可。

    MVP下Activity和Fragment体如今了这一 层,Activity一般也就做载入UI视图、设置监听再交由Presenter处理的一些工作。所以也就须要持有相应Presenter的引用。

    处理一些基本UI逻辑。推断是否为空。

    (3)Presenter层

    Presenter这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做详细的业务操作。

    MVP架构和MVC架构差别:

    这里写图片描写叙述

    MVC中是同意Model和View进行交互的,而MVP中,Model与View之间的交互由Presenter完毕。另一点就是Presenter与View之间的交互是通过接口的。

    3、MVP实现

    百说不如一做。实现一个简单的登录操作。

    项目结构例如以下:
    这里写图片描写叙述

    (1)Model层实现
    首先实现User实体类:

    package com.chunsoft.blogcontent.bean;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:19
     * Email:chun_soft@qq.com
     * Content:实体类
     */
    
    public class User {
    
        private String username;
        private String password;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    model层主要实现业务逻辑处理,在本文案例中,主要逻辑处理就是登录,抽取了一个接口和一个实现类,在login操作,模拟登录操作,Thread.sleep()模拟耗时。因为是耗时操作,通过一个回调接口通知登录状态。

    model层接口:

    package com.chunsoft.blogcontent.model;
    
    import com.chunsoft.blogcontent.RequestCallback;
    import com.chunsoft.blogcontent.bean.User;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:30
     * Email:chun_soft@qq.com
     * Content:Model层主要处理业务方法和实体模型
     */
    
    public interface LoginModel {
        void login(String username, String password, RequestCallback<User> callback);
    }

    model层接口实现:

    package com.chunsoft.blogcontent.model.impl;
    
    import com.chunsoft.blogcontent.RequestCallback;
    import com.chunsoft.blogcontent.bean.User;
    import com.chunsoft.blogcontent.model.LoginModel;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:31
     * Email:chun_soft@qq.com
     * Content:Model层的实现
     */
    
    public class LoginModelImpl implements LoginModel{
        @Override
        public void login(final String username, final String password, final RequestCallback<User> callback) {
            //模仿登录操作
            new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(2*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if ("chunsoft".equals(username) && "123456".equals(password)) {
                        User user = new User();
                        user.setUsername(username);
                        user.setPassword(password);
                        callback.onSuccess(user);
                    } else {
                        callback.onFailure("登录失败");
                    }
                }
            }.start();
        }
    }
    

    回调接口:

    package com.chunsoft.blogcontent;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:35
     * Email:chun_soft@qq.com
     * Content:回调接口
     */
    
    public interface RequestCallback<T> {
        void onSuccess(T datas);
        void onFailure(String msg);
    }

    (2)View层实现

    对于View层接口定义,首先考虑功能上的操作,然后考虑:

    • 该操作须要什么?(getUserName等)
    • 该操作的结果。相应的反馈?(toMainActivity等)
    • 该操作过程中交互友好?( showLoading)

    view层接口:

    package com.chunsoft.blogcontent.view;
    
    import com.chunsoft.blogcontent.bean.User;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:54
     * Email:chun_soft@qq.com
     * Content:view层接口
     */
    
    public interface LoginView {
        String getUserName();
        String getPassword();
    
        void showLoading();
        void hideLoading();
    
        void toMainActvity(User user);
        void showFailedError(String msg);
    }

    view层实现,事实上就是Activity,能够看到Activity的代码量大大降低,且逻辑清晰:

    package com.chunsoft.blogcontent;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.Toast;
    
    import com.chunsoft.blogcontent.bean.User;
    import com.chunsoft.blogcontent.presenter.impl.LoginPresenterImpl;
    import com.chunsoft.blogcontent.view.LoginView;
    
    public class MainActivity extends AppCompatActivity implements LoginView{
    
        private EditText et_mobile,et_password;
        private ProgressBar pb;
        private Button btn_login;
    
        private LoginPresenterImpl mLoginPresenter = new LoginPresenterImpl(this);
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            et_mobile = (EditText) findViewById(R.id.et_mobile);
            et_password = (EditText) findViewById(R.id.et_password);
            pb = (ProgressBar) findViewById(R.id.pb);
            btn_login = (Button) findViewById(R.id.btn_login);
    
            btn_login.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mLoginPresenter.login();
                }
            });
        }
    
        @Override
        public String getUserName() {
            return et_mobile.getText().toString();
        }
    
        @Override
        public String getPassword() {
            return et_password.getText().toString();
        }
    
        @Override
        public void showLoading() {
            pb.setVisibility(View.VISIBLE);
        }
    
        @Override
        public void hideLoading() {
            pb.setVisibility(View.INVISIBLE);
        }
    
        @Override
        public void toMainActvity(User user) {
            Toast.makeText(this,user.getUsername() + "登录成功",Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void showFailedError(String msg) {
            Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
        }
    }

    (3)Presenter层实现

    Presenter层是Model层和View层的桥梁。本文中依旧抽象出一个接口和一个实现类,定义时主要看该功能有什么操作,比如。登录:

    Presenter接口:

    package com.chunsoft.blogcontent.presenter;
    
    /**
     * Developer:chunsoft on 2017/2/7 11:49
     * Email:chun_soft@qq.com
     * Content:Presenter层接口
     */
    public interface LoginPresenter {
        void login();
    }

    Presenter层实现:

    package com.chunsoft.blogcontent.presenter.impl;
    
    import android.os.Handler;
    
    import com.chunsoft.blogcontent.RequestCallback;
    import com.chunsoft.blogcontent.bean.User;
    import com.chunsoft.blogcontent.model.LoginModel;
    import com.chunsoft.blogcontent.model.impl.LoginModelImpl;
    import com.chunsoft.blogcontent.presenter.LoginPresenter;
    import com.chunsoft.blogcontent.view.LoginView;
    
    
    /**
     * Developer:chunsoft on 2017/2/7 11:50
     * Email:chun_soft@qq.com
     * Content:Presenter层实现
     */
    
    public class LoginPresenterImpl implements LoginPresenter {
    
        private LoginView loginView;
        private LoginModel loginModel;
    
        private Handler mHandler = new Handler();
    
        //在构造函数中初始化
        public LoginPresenterImpl(LoginView loginView) {
            this.loginModel = new LoginModelImpl();
            this.loginView = loginView;
        }
    
        @Override
        public void login() {
            loginView.showLoading();
            loginModel.login(loginView.getUserName(), loginView.getPassword(), new RequestCallback<User>() {
                @Override
                public void onSuccess(final User datas) {
                    //登录成功
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            loginView.toMainActvity(datas);
                            loginView.hideLoading();
                        }
                    });
                }
    
                @Override
                public void onFailure(final String msg) {
                    //登录失败
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            loginView.showFailedError(msg);
                            loginView.hideLoading();
                        }
                    });
                }
            });
        }
    }

    Presenter层是Model层和View层的桥梁,Model层和View层不直接通信。所以Presenter层须要Model层和View层的实现类。从View层中获取重要參数,交给Model 层调用业务逻辑处理,运行后的结果和反馈再交给View层去展示。

    本文源代码下载

    本文是简单的用MVP架构实现登录操作,而眼下主流开发,将Rxjava、Retrofit和MVP结合进行开发,逻辑更加清晰,下篇文章将详细介绍这部分实现。

  • 相关阅读:
    我给老师发的邮件
    [LeetCode]Sum Root to Leaf Numbers
    [LeetCode]Binary Tree Inorder Traversal
    [LeetCode]Merge Sorted Array
    [LeetCode]Unique Paths II
    [LeetCode]Unique Paths
    [LeetCode]Sort Colors
    [LeetCode]Balanced Binary Tree
    [LeetCode]Valid Palindrome
    [LeetCode]Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7365429.html
Copyright © 2011-2022 走看看