MVP

作者: Amy木婉清 | 来源:发表于2022-01-10 14:18 被阅读0次

MVP耦合图示:

image.png
MVP使用交互流程图示:
image.png
MVP全称是Model-View-Presenter,是模型(model)-视图(view)-呈现器(Presenter)的缩写。
Model:业务逻辑和数据处理(数据库存储操作,网络数据请求,复杂算法。耗时操作)
View:对应与Activity,负责View的绘制以及与用户交互
Presenter:负责完成View与Model间的交互(有一点还需注意,presenter是双向绑定的关系,因此,在设计的时候就要注意到接口和抽象的使用,尽可能的降低代码的耦合度,这也是mvp的宗旨)
责任划分
Model:定义并实现获取数据操作(如数据库读取、网络加载)的接口
View:定义并在Activtiy、Fragment等中实现用于界面处理(初始化、数据展示)的接口
Presenter:定义用于调用Model的数据请求方法的接口,实现此接口,并实现Model中定义的数据请求接口
项目结构
image.png
Step 1、编写Model逻辑

数据请求接口(如数据库读取、网络加载)的定义

  /**
     * Model层接口--实现该接口的类负责世界的数据获取操作,如数据库读取、网络加载
     */

    public interface IModel{

        void getData(Model.LoadDataCallback callback);
    }

数据请求接口的实现

    /**
     * 实现IModel接口、负责实际的数据获取操作(数据库读取、网络加载等),然后通过自己的接口(LoadDataCallback)反馈出去
     */

    public class Model implements IModel{

        @Override
        public void getData(final LoadDataCallback callback) {
            //数据获取操作、如数据库查询、网络加载等

            new Thread(){
                @Override
                public void run() {
                    try {
                        //模拟耗时操作
                        Thread.sleep(3000);
                        //获取到了数据
                        String data="我是获取到的数据";
                        //将获取到的数据通过接口反馈出去
                        callback.success(data);
                    } catch (Exception e) {
                        e.printStackTrace();
                        //获取数据失败的回调
                        callback.failure();
                    }
                }
            }.start();
        }
        /**
         * 用于回传请求的数据的回传
         */

        public interface  LoadDataCallback{
            void success(String taskId);

            void failure();
        }
    }
Step2/编写View逻辑

定义用于界面处理(初始化,数据展示)的接口

/**
 * View层接口---执行各种UI操作,定义的方法主要是给Presenter中来调用的
 */
public interface IView {

    void showLoadingProgress(String message);

    void showData(String text);
}

在Activtiy 、Fragment等中对接口的实现:

/**
 * 实现IView接口并实现各种UI操作的方法(其他的业务逻辑在Presenter中进行操作)
 */
public class ViewActivity extends AppCompatActivity implements IView {

    private Button mBtnShowToast;
    private TextView mText;
    private MyHandler mHandler = new MyHandler(ViewActivity.this);
    private IPresenter mPresenter;

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

        //实例化Presenter,并将实现了IView接口的类传入进去
        mPresenter = new Presenter(ViewActivity.this);

        mBtnShowToast = findViewById(R.id.btn_show_toast);
        mText = findViewById(R.id.text);

        mBtnShowToast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过Presenter来实现业务逻辑操作,View层只负责UI相关操作
                mPresenter.loadData();
            }
        });
    }

    @Override
    public void showLoadingProgress(final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(message);
            }
        });
    }

    @Override
    public void showData(final String text) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(text);
            }
        });
    }

    private static class MyHandler extends Handler {

        //弱引用,防止内存泄露
        WeakReference<ViewActivity> weakReference;

        public MyHandler(ViewActivity activity) {
            this.weakReference = new WeakReference<ViewActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    weakReference.get().mText.setText(msg.what);
                    break;
            }
        }
    }
}
Step3/编写Presenter逻辑(重点)

presenter层很重要,因为MVP模式中,View和Model通过presenter纽带进行交互----
View通过presenter对象来调用Model中数据请求的接口,而Model中数据请求的结果会通过presenter中定义的接口回调给presenter,然后在通过presenter通知给view

定义用于调用Model中的数据请求方法的接口具体实现:

    /**
     * Presenter层接口--控制Model层的数据库操作及调用View层的UI操作来完成“中间人”工作
     */

    public interface IPresenter {

        void loadData();
    }

定义用于调用Model中的数据请求方法的接口,实现此接口,并实现M中定义的数据请求的接口

/**
 * Presenter层接口---控制Model层的数据操作及调用View层的UI操作来完成“中间人”工作.
 * 用于model和view的相关方法的调用
 */
public class Presenter implements IPresenter, Model.LoadDataCallback {

    private final IView mView;
    private final Model mModel;

    public Presenter(IView view) {
        mView = view;
        mModel = new Model();
    }

    @Override
    public void loadData() {
        mView.showLoadingProgress("加载数据中");
        mModel.getData(Presenter.this);
    }

    @Override
    public void success(String data) {
        mView.showData(data);
    }

    @Override
    public void failure() {

    }
}
MVP与MVC区别
MVC结构示意图
image.png
MVP结构示意图
image.png
MVP MVC区别
1.Activity职责不同

Activtiy在MVP中时View层,在MVC中是Controller层,这是MVC 和MVP很主要的一个区别,可以说Android从MVC转向MVP开发也主要是优化Activity的代码,避免Activtiy的代码臃肿庞大

2.View层不同

MVC的View层指的是XML布局文件或者是用Java自定义的View,MVP层的View是Activtiy或者Fragment。使用传统的MVC,其中的View对应的是各种Layout布局文件,但是这些布局文件中并不像web端那样强大,能做的事情非常有限。MVP的View层Activity在实际项目中,随着逻辑的复杂度越来越大,Activtiy臃肿的缺点仍然体现出来了,因为Activtiy中还是充满了大量与View层无关的代码,比如各种事件的处理派发,就如MVC中的那样View层和Controller代码耦合在一起。

3.控制层不同。

MVC控制层是Activtiy,或者是Fragment,Controller对应的是Activity,而Activity中又具有操作UI的功能,我们在实际的项目中也会有很多UI操作在这一层,也做了很多View中应该做的事情,当然Controller层Activity中包含应该做的事情,比如各种事件的派发回调,而且在一层中我们会根据时间再去调用Model层操作数据,所以这种MVC的方式在实际项目中,Activtiy所在的Controller是非常重要的,各层次之间的耦合情况也比较严重,不方便单元测试。MVP的控制层是Presenter,里面没有很多的实际东西,主要是做Model和View层的交互。

4.关系链不同

MVP中Model层与View层是没有关系的,彼此不会通讯和操作,Model与View的通讯都是Presenter层来传达的。但是在MVC中,Model和View是存在交互的。比如我们自定义的View空间里面肯定要使用Model的数据,View也要根据不同的Model数据做出不同的展现。在MVP中,接口就可以完成。

5.适用范围不同

在Android中,MVP和MVC都有自己的适用情况。使用MVP可以更好的解耦三大模块,模块之间比较清晰,也很方便使用MVP来组件化架构整体项目。在组件化的Module或者中间件我们可以使用MVC,Module或者中间件中不会存在很复杂的View层,使用MVC更加方便

6.交互方式不同

MVP通讯交互基本都是通过接口的,MVC中的通讯交互很多时候都是调用对象的方法

7.实现方法不同

MVC和MVP的Model几乎是一样的,都是处理数据,只要不在Activity或者Fragment中请求数据,其他的所有控制都放在Activity或者Fragment中,这样写基本就是MVC,但是容易造成Activtiy代码冗余。用MVP则需要写很多View和Presenter接口来实现模块之间的通讯,会增加很多类。

相同点

优点:
降低耦合度
模块职责画风明显
利于测试驱动开发
代码复用
隐藏数据
代码灵活性
缺点:
额外的代码复杂度及学习成本

不同点:
MVP模式:
View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
Presenter与VView的交互是用过接口来进行的,更有利于添加单元测试
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑,业务相似的时候也可以多个View共享一个Presenter
MVC模式:
View可以与Model直接交互
Controller是基于行为的,并且可以被多个View共享
Controller可以负责决定显示哪个View

相关文章

  • Android MVP

    Android MVP初探 Android MVP进阶 Android MVP高级 Android MVP扩展

  • MVP / RxJava / Retrofit / RxBus

    MVP Android MVP 详解(上) Android MVP 详解(下) Android中的MVP模式,带实...

  • 一套完整的Android通用框架

    转自吴小龙同学的博客 MVP模式 MVP简介 Android MVP Sample,MVP+Retrofit+Rx...

  • MVP简单尝试

    MVP模式解析 标签: Android 架构 MVP MVP模式的核心思想 MVP将Activity中的U...

  • MVP基础架构

    MVP 是什么 基础架构 登录例子 MVP的优缺点 一、MVP 是什么 MVP全名是 Model - View -...

  • android 安卓 mvp mvvm - mvp

    android 安卓 mvp mvvm - mvpandroid 安卓 mvp mvvm - mvvm MVP M...

  • MVP架构

    目录 1)MVP简介2)MVP实例 1)MVP简介 MVP模式将Activity中的业务逻辑全部剥离出来,Acti...

  • MVC和MVP

    Android mvp 架构的自述 如何更高效的使用MVP以及官方MVP架构解析 老的MVC架构 新的MVP架构 ...

  • MVP系列-Android平台-第1讲-初探MVP

    MVP系列-Android平台-第1讲-初探MVP 内容一:什么是MVP?什么是MVC? 第一点:什么是MVP? ...

  • MVP框架学习

    一、MVP介绍 二、为什么使用MVP模式 三、MVP与MVC的异同 四、使用MVP实现Android的登录的Dem...

网友评论

    本文标题:MVP

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