MVC MVP MVVM 分别是什么?

MVC及其优缺点

答案参考自:

概念

MVC全名是Model-View-Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。

MVC

MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。更好的调节M和V的搭配。

MVC是一种框架模式,说到底是一种框架,而不是一种设计模式,框架通常是代码重用,而设计模式是设计重用,而架构则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。

优点

分层,结构清晰,耦合性低,大型项目代码的复用性得到极大的提高,开发人员分工明确,提高了开发的效率,维护方便,降低了维护成本。

缺点

简单的小型项目,使用MVC设计反而会降低开发效率,层和层虽然相互分离,但是之间关联性太强,没有做到独立的重用。

MVP及其优缺点

答案参考自:

概念

实际上按照代码在 App 中所处位置,描述为 VPM 更合适,即 View -> Presenter -> Model:

MVP

这个架构的核心就是 View 与 Presenter 都被抽象成了接口,是面向接口编程的一个实践。因为面向接口,所以实现了依赖隔离,即无需知道具体的 Class 类型。

优点

  1. 模块职责划分明显,层次清晰,接口功能清晰,遵循了单一职责类的设计原则,提升了代码的可维护性.
  2. 降低耦合度,Model层和View层分离,解耦.修改View而不影响Model.
  3. 功能复用度高,方便.一个Presenter可以复用于多个View,而不用更改Presenter的逻辑.
  4. 有利于测试驱动开发,以前的Android开发是难以进行单元测试.
  5. 代码灵活性,如果后台接口还未写好,但已知返回数据类型的情况下,完全可以写出此接口完整的功能.

缺点

  1. 其实这并不是 MVP 架构的痛点,而是整个 Android App 开发的痛点,那就是对 UI 的操作必须在 Activity 与 Fragment 的生命周期之内,更细致一点,最好在 onStart() 之后 onPause()之前,否则极其容易出现各种异常。而 MVP 架构中,Presenter 对 Activity 与 Fragment 的生命周期是无感知的,所以我们需要手动添加相应的生命周期方法,并进行特殊处理,以避免出现异常或内存泄露。
  2. MVP中接口过多.
  3. 每一个功能,相比于MVC要多写好几个文件.
  4. 如果某一个界面中需要请求多个服务器接口,这个界面文件中会实现很多的回调接口,导致代码繁杂.
  5. 如果更改了数据源和请求中参数,会导致更多的代码修改.
    额外的代码复杂度及学习成本.
  6. 由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。

MVVM及其优缺点

答案参考自:

概念

MVVM

View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

在MVVM中,数据是核心,由于ViewModel与View之间的双向绑定,操作了ViewModel中的数据,就会同步到DOM,我们透过DOM事件监控用户对DOM的改动,也会同步到ViewModel。

MVVM 架构相对复杂,核心是 LifecycleOwner、LifecycleObserver、LifecycleRegistry 组件,在此之上,Google 还开发了 DataBinding、ViewModel、LiveData 以实现完整的 MVVM 架构。相关组件已收纳至 JetPack Architecture 中。

MVVM

这个架构的核心就是 ViewModel 和 LiveData。ViewModel 的作用是保证当设备因配置改变而重新创建 FragmentActivity(目前 ViewModel 仅支持 FragmentActivity 和 Fragment) 时,数据也不会丢失。LiveData 的作用是保证只在 FragmentActivity 或 Fragment 的生命周期状态为 [onStarted, onResumed] 时,回调 onChanged(T data),所以我们可以在 onChanged() 中安全的更新 UI。下面简单介绍源码中是如何实现的:

优点

  • ViewModel:因设备配置改变导致 Activity 重建时,无需从 Model 中再次加载数据,减少了 IO 操作

  • LiveData:更新 UI 时,不用再关注生命周期问题

  • Data Binding: 可以有效减少模板代码的编写,而且目前已经支持双向绑定 (注意:不是所有的 UI 都需要使用 Data Binding,虽然通过 @BindingAdapter 我们真的可以“为所欲为”,最好还是只用于需要绑定 Bean 类的布局)

缺点

  • LiveData 本身是没有 public 方法的,所以我们应该使用其子类 MutableLiveData。这样设计,我们就可以在 Model 中使用 MutableLiveData,在 ViewModel 中,只对 View 提供 LiveData,避免 View 去更新 LiveData。

MVP如何防止内存泄漏

  • BasePresenter中使用对View的弱引用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    public abstract class BasePresenter<M extends BaseModel, V extends BaseView, CONTRACT> {
    protected M m;
    protected WeakReference<V> weakReference;

    public BasePresenter() {
    this.m = getModel();
    }

    protected void bindView(V v) {
    weakReference = new WeakReference<>(v);
    }

    protected void unbindView() {
    if (weakReference != null) {
    weakReference.clear();
    weakReference = null;
    System.gc();
    }
    }

    protected V getView() {
    if (weakReference != null)
    return weakReference.get();
    return null;
    }

    protected abstract CONTRACT getContract();
    protected abstract M getModel();
    }
  • BaseViewonCreateonDestory方法中主动绑定和解绑Presenter,防止内存泄漏。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public abstract class BaseView<P extends BasePresenter, CONTRACT> extends Activity {
    protected P p;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    p = getPresenter();
    p.bindView(this);
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    p.unbindView();
    }

    protected abstract P getPresenter();
    protected abstract CONTRACT getContract();
    }

TODO

  1. MVP如何管理Presenter的生命周期,何时取消网络请求

MVC MVP MVVM 分别是什么?
https://luoyuy.top/posts/02e5ea5a6473/
作者
LuoYu-Ying
发布于
2022年5月25日
许可协议