IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> MVC、MVP、MVVM -> 正文阅读

[移动开发]MVC、MVP、MVVM

MVC、MVP、MVVM

MVCMVPMVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式。不同于设计模式(Design Pattern),只是为了解决一类问题而总结出的抽象方法,一种架构模式往往使用了多种设计模式。

architectural [?ɑ?rk??tekt??r?l] 建筑学的,建筑上的 pattern [?p?t?rn] 模式,方式

MVCMVPMVVM不同部分是C(Controller)P(Presenter)VM(View-Model),而相同的部分则是MV(Model-View)Model层用于封装和应用程序的业务逻辑相关的数据以及对数据的处理方法。View作为视图层,主要负责数据的展示。

1 MVC

通过Model&View完成了数据从模型层到视图层的逻辑。但对于一个应用程序,这远远是不够的,还需要响应用户的操作、同步更新ViewModel。于是,在MVC中引入了控制器Controller,让它来定义用户界面对用户输入的响应方式,它连接模型和视图,用于控制应用程序的流程,处理用户的行为和数据上的改变。

MVC

  • 模型层(Model):用来存储业务的数据,一旦数据发生变化,模型将通知有关的视图。Model是与View无关, 而与业务相关的。对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的;
  • 视图层(View):一般采用XML文件进行界面的描述`;
  • 控制层(Controller):Android的控制层的重任通常落在了众多的Activity的肩上;

MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。

随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。

2 MVP

当我们将Activity复杂的逻辑处理移至另外的一个类(Presenter)中时,Activity其实就是MVP模式中的View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理)。

MVPPresenter是框架的控制者,承担了大量的逻辑操作,而MVCController更多时候承担一种转发的作用。因此在APP中引入MVP的原因,是为了将此前在Activty中包含的大量逻辑操作放到控制层中,避免Activity的臃肿。

MVP

  • 模型层(Model):负责存储、检索、操纵数据,有时也实现一个Model interface用来降低耦合;
  • 视图层(View):负责显示数据,并向Presenter报告用户行为。与用户进行交互,在Android中体现为Activity;
  • 业务逻辑层(Presenter):负责逻辑处理,从Model拿数据,回显到UI层,响应用户的行为;

google todo-mvp加入契约类来统一管理ViewPresenter的所有的接口,这种方式使得ViewPresenter中有哪些功能,一目了然

优点:

  • 分离视图逻辑和业务逻辑,降低了耦合,修改视图而不影响模型,不需要改变Presenter的逻辑。模型与视图完全分离,我们可以修改视图而不影响模型;
  • 视图逻辑和业务逻辑分别抽象到了ViewPresenter的接口中,Activity只负责显示,代码变得更加简洁,提高代码的阅读性;
  • Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试;

Presenter是通过interfaceView(Activity)进行交互的,这说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间(不需要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试)

缺点:

  • 那就是对UI的操作必须在ActivityFragment的生命周期之内,更细致一点,最好在onStart()之后onPause()之前,否则极其容易出现各种异常,内存泄漏;
  • PresenterView之间的耦合度高,app中很多界面都使用了同一个Presenter 。一旦需要变更,那么视图需要变更了;

MVP如何设计避免内存泄漏?

MVP模式在封装的时候会造成内存泄漏,因为Presenter层,需要做网络请求,所以就需要考虑到网络请求的取消操作,如果不处理,Activity销毁了,Presenter层还在请求网络,就会造成内存泄漏。

如何解决MVP模式造成的内存泄漏?只要Presenter层能感知Activity生命周期的变化,在Activity销毁的时候,取消网络请求,就能解决这个问题。

下面开始封装ActivityPresenter。定义IPresenter声明Activity(Fragment)生命周期中的各个回调方法:

public interface IPresenter {

    <U extends IUI> void init(BaseActivity activity, U ui);

    /**
     * onUICreate:UI被创建的时候应该invoke这个method. <br/>
     * <p/>
     * 比如Activity的onCreate()、Fragment的onCreateView()的方法应该调用Presenter的这个方法
     *
     * @param savedInstanceState 保存了的状态
     */
    void onUICreate(Bundle savedInstanceState);

    /**
     * onUIStart:在UI被创建和被显示到屏幕之间应该回调这个方法. <br/>
     * <p/>
     * 比如Activity的onStart()方法应该调用Presenter的这个方法
     */
    void onUIStart();

    /**
     * onUIResume:在UI被显示到屏幕的时候应该回调这个方法. <br/> 
     * <p/>
     * 比如Activity的onResume()方法应该调用Presenter的这个方法
     */
    void onUIResume();

    /**
     * onUIPause:在UI从屏幕上消失的时候应该回调这个方法. <br/> 
     * <p/>
     * 比如Activity的onPause()方法应该调用Presenter的这个方法
     */
    void onUIPause();

    /**
     * onUIStop:在UI从屏幕完全隐藏应该回调这个方法. <br/>
     * <p/>
     * 比如Activity的onStop()方法应该调用Presenter的这个方法
     */
    void onUIStop();

    /**
     * onUIDestroy:当UI被Destory的时候应该回调这个方法. <br/>
     */
    void onUIDestroy();

    /**
     * onSaveInstanceState:保存数据. <br/> 
     * <p/>
     * * 一般是因为内存不足UI的状态被回收的时候调用
     * 
     * @param outState 待保存的状态
     */
    void onSaveInstanceState(Bundle outState);

    /**
     * * onRestoreInstanceState:当UI被恢复的时候被调用. <br/>
     * 
     * @param savedInstanceState 保存了的状态
     */
    void onRestoreInstanceState(Bundle savedInstanceState);
}

封装BaseActivity拥有一个protected P mPresenter实例,类型写成泛型,protected修饰,子类实现构造方法中,对mPresenter进行实例化:采用反射的形式(避免让子类进行实例化,繁琐):

public abstract class BaseMVPActivity<P extends IPresenter> extends BaseActivity {
    protected P mPresenter;

    public BaseMVPActivity() {
        this.mPresenter = createPresenter();
    }

    protected P createPresenter() {
        ParameterizedType type = (ParameterizedType) (getClass().getGenericSuperclass());
        if (type == null) {
            return null;
        }
        Type[] typeArray = type.getActualTypeArguments();
        if (typeArray.length == 0) {
            return null;
        }
        Class<P> clazz = (Class<P>) typeArray[0];
        try {
            return clazz.newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onDestroy() {
        mPresenter.onUIDestroy();
        super.onDestroy();
    }
}

封装BasePresenter。定义BasePresenter,页面销毁的回调里面。处理网络请求定义一个集合,把每次网络请求装载到集合里面,在页面销毁的时候,取消所有的网络请求。防止内存泄漏。

public abstract class BasePresenter<U extends IUI> implements IPresenter {
    @Override
    public void onUIDestroy() {
    }
}

MVCMVP区别

ViewModel并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVCView可以与Model直接交互。MVP隔离了MVC中的MV的直接联系后,靠Presenter来中转,所以使用MVPP是直接调用View的接口来实现对视图的操作的。

MVC&MVP

3 MVVM

MVVM可以算是MVP的升级版,其中的VMViewModel的缩写,ViewModel可以理解成是View的数据模型和Presenter的合体,ViewModelView之间的交互通过Data Binding完成,而Data Binding可以实现双向的交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity的压力。

DataBinding用来实现View层与ViewModel数据的双向绑定,Data Binding减轻原本MVPPresenter要与 p 和 View 互动的职责

MVP

  • 模型层(Model):即数据模型,用于获取和存储数据;
  • 视图模型层(ViewModel):与Presenter大致相同,都是负责处理数据和实现业务逻辑,但ViewModel层不应该直接或者间接地持有View层的任何引用;
  • 视图层(View):包含布局,以及布局生命周期控制器(Activity/Fragment);

MVVM的本质是数据驱动,把解耦做的更彻底,ViewModel不持有View

View产生事件,使用ViewModel进行逻辑处理后,通知Model更新数据,Model把更新的数据给ViewModelViewModel自动通知View更新界面,而不是主动调用View的方法

MVVM的优点:

核心思想是观察者模式,它通过事件和转移View层数据持有权来实现View层与ViewModel层的解耦。

  • 耦合度更低,复用性更强,没有内存泄漏;
  • 结合Jetpack,写出更优雅的代码;

缺点:

ViewModelView层的通信变得更加困难了,所以在一些极其简单的页面中请酌情使用,在使用MVP这个道理也依然适用。

参考

https://blog.csdn.net/lihaoxiang123/article/details/78977181

https://blog.csdn.net/caijunfen/article/details/78478438

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:11:02  更:2022-01-16 13:11:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:52:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码