探究 Android MVC、MVP、MVVM 的区别以及优缺点

2024-05-28 11:32

本文主要是介绍探究 Android MVC、MVP、MVVM 的区别以及优缺点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 1. MVC
    • MVC
    • MVC 优点
    • MVC 缺点
  • 2. MVP
    • MVP 优点
    • MVP 缺点
  • 3. MVVM
    • MVVM 概念
    • MVVM 优点
    • MVVM 缺点
  • 4. Why use Jetpack + MVVM?
  • 5. 总结:我理解中的 MVVM
    • 5.1 相较于 MVC 和 MVP 的优势
      • 1. 解决了各个层级之间耦合度太高的问题
      • 2. 解决了代码量太多,或者模式化代码太多的问题
      • 3. 解决了可能会有的内存泄漏问题
      • 4. 解决了因为Activity停止而导致的View空指针问题
      • 5. 解决了生命周期管理问题
    • 5.2 最后再说说MVVM为什么这么强大?
  • 参考链接

1. MVC

MVC

  • 架构介绍
    • Model:数据模型,负责处理数据的加载或存储,比如我们从数据库或者网络获取数据
    • View:视图,负责界面数据的展示,与用户进行交互,也就是我们的xml布局文件
    • Controller:控制器,负责逻辑业务的处理,也就是我们的Activity

MVC 优点

简单,上去就是复制粘贴一顿怼
MVC流程图.png

  • 1.View 接受用户的请求,然后将请求传递给 Controller
  • 2.Controller 进行业务逻辑处理后,通知 Model去更新
    1. Model 数据更新后,通知 View 去更新界面显示
    • 这里容易发生耦合

  • View --> Controller,也就是反应 View 的一些用户事件(点击触摸事件)到Activity上
  • Controller --> Model, 也就是 Activity 去读写一些我们需要的数据
  • Controller --> View, 也就是 Activity 在获取数据之后,将更新内容反映到View上`

MVC 缺点

  • Android中使用了 Activity 来充当 Controller,但实际上一些 UI 也是由 Activity 来控制的,比如进度条等。因此部分视图就会跟 Controller 捆绑在同一个类了。同时,由于 Activity 的职责过大,Activity 类的代码也会迅速膨胀
    • 主要表现就是我们的 Activity 太重了,经常一写就是几百上千行了。造成这种问题的原因就是 Controller 层和 View 层的关系太过紧密,也就是Activity 中有太多操作 View 的代码了
  • MVC还有一个重要的缺陷就是 ViewModel 是有交互的,没有做到完全的分离,这就会产生耦合。

PS: 但是!但是!其实Android这种并称不上传统的MVC结构,因为Activity又可以叫View层又可以叫Controller层,所以我觉得这种Android默认的开发结构,其实称不上什么MVC项目架构,因为他本身就是Android一开始默认的开发形式,所有东西都往Activity中丢,然后能封装的封装一下,根本分不出来这些层

2. MVP

PS:之前不就是因为Activity中有操作view,又做Controller工作吗。所以其实MVP架构就是从原来的Activity层把view和Controller区分开单独抽出来一层Presenter作为原来Controller的职位

然后最后演化成,View 层写成接口的形式,然后Activity去实现View接口,最后在Presenter类中去实现方法

总之呢,就是解决:

  • ControllerView彻底分离。
  • 解决 MVCActivity 职责过多,代码臃肿

的问题。
MVP流程图.png


  • Model:数据模型,比如我们从数据库或者网络获取数据
    • MVC不同的地方在于 Model 不会跟 View 发生交互,只会跟 Presenter 交互
  • View:视图,也就是我们的xml布局文件和Activity
    • MVP在实现上来说可以有多种思路,不同的实现方式其优缺点也是不同的,具体问题具体分析
    • eg: 也有场景下 Activity 作为 Presenter 会更好一些
  • Presenter:主持人,单独的类,只做调度工作。

  • View --> Presenter,反应 View 的一些用户事件到 Presenter上。
  • Presenter --> Model, Presenter去读写操作一些我们需要的数据。
  • Presenter--> View, Presenter在获取数据之后,将更新内容反馈给 Activity,进行 view 更新。

通常View与Presenter是一对一的,但复杂的View可以绑定多个Presenter来处理逻辑。

MVP 优点

这种的优点就是确实大大减少了 Activity 的负担,让 Activity 主要承担一个更新 View 的工作,然后把跟 Model 交互的工作转移给了 Presenter,从而由Presenter方来控制和交互 Model方以及 View。所以让项目更加明确简单,顺序性思维开发。

  • ViewModel 完全分离,我们可以修改视图而不影响模型。
  • 可以更高效地使用模型,因为所有的交互都发生 Presenter
  • PresenterView 的交互是通过接口来进行的,有利于添加单元测试。

MVP 缺点

缺点也很明显:

  • 首先就是代码量大大增加了,每个页面或者说功能点,都要专门写一个Presenter类,并且由于是面向接口编程,需要增加大量接口,会有大量繁琐的回调。
    • 页面逻辑复杂的话,相应的接口也会变多,增加维护成本
  • 其次,由于 Presenter 里持有了 Activity 对象,所以可能会导致内存泄漏或者view 空指针,这也是需要注意的地方。
  • 系统内存不足时,系统会回收 Activity。一般我们都是用OnSaveInstanceState() 去保存状态,用 OnRestoreInstanceState() 去恢复状态。但是在我们的MVP中,View层是不应该去直接操作 Model的,所以这样做不合理,同时也增大了MV的耦合。
    • 解决办法是不要将 Activity 作为View 层,可以把ActivityPresenter来处理。具体实现这里就不分析了,有兴趣的可以研究一下
  • UI 改变的话,比如 TextView 替换 EditText,可能导致 Presente 的一些更新UI 的接口也跟着需要更改,存在一定的耦合

3. MVVM

MVVM 概念

MVVM流程图.png

Google 官方加持,更新了 Jetpack 中很多架构组件,比如 ViewModelLivedataDataBinding等等,所以这个是现在的主流框架和官方推崇的框架。

Model:数据模型,比如我们从数据库或者网络获取数据。View:视图,也就是我们的xml布局文件和Activity。ViewModel:关联层,将Model和View绑定,使他们之间可以相互绑定实时更新


  • Model:模型层,负责处理数据的加载或存储。与 MVP中的M一样。
  • View:视图层,负责界面数据的展示,与用户进行交互。与MVP中的V一样。
  • ViewModel:视图模型,负责完成 ViewModel 间的交互,负责业务逻辑。

  • ViewViewModel 进行绑定,能够实现双向的交互
    • ViewModel数据改变时,View 会相应变动 UI,反之亦然
  • ViewModel 进行业务逻辑处理,通知 Model 去更新
    • 可以与 View 实现 databinding 双向绑定 , 使他们之间可以相互绑定实时更新
  • Model 数据更新后,把新数据传递给 ViewModel
    • eg: Activity 中监听 viewModel.value 变化,监听到之后改变 view 的值

  • View --> ViewModel -->View,双向绑定,数据改动可以反映到界面,界面的修改可以反映到数据
  • ViewModel --> Model, 操作一些我们需要的数据

MVVM 优点

MVVM 已经被实践证明是一种优秀的设计模式。能很好地将 UI 、交互逻辑、业务逻辑数据 解耦

  • 降低 ViewController 的耦合,减轻了视图的压力
    • Activity 代码不会像 MVC 那样那么臃肿,方便维护
  • 相比于 MVPPresenteView 存在耦合。ViewModelView 的耦合则更低,ViewModel 只负责处理和提供数据,UI的改变,比如TextView 替换 EditText,ViewModel 几乎不需要更改任何代码,只需专注于数据处理就可以了。
  • ViewModel 里面只包含数据和业务逻辑,没有UI的东西,方便单元测试。

MVVM 缺点

  • 数据绑定使得程序较难调试
    • 界面出现异常时,有可能是 View 的代码有问题,也可能是 Model 的代码有问题。
    • 由于数据绑定使得数据能够快速传递到其他位置,因此要定位出异常就比较有难度了。

4. Why use Jetpack + MVVM?

我们通常使用 Jetpack 配合 MVVM 一起使用,为什么呢?

  • 快速开发
    • 组件可以单独采用(不过这些组件是为协同工作而构建的),同时利用 Kotlin 语言功能帮助您提高工作效率。
  • 消除样板代码
    • Android Jetpack 可管理繁琐的 Activity(如后台任务、导航和生命周期管理),以便您可以专注于如何让自己的应用出类拔萃。
  • 构建高质量的强大应用
    • Android Jetpack 组件围绕现代化设计实践构建而成,具有向后兼容性,可以减少崩溃和内存泄漏。

开发者可以减少许多样板代码的书写,只需要通过模版工具自动生成就可以了,在取缔非常多的耗时的重复工作的同时,减少了很多因为忘记 unRegister带来的各种问题

5. 总结:我理解中的 MVVM

5.1 相较于 MVC 和 MVP 的优势

1. 解决了各个层级之间耦合度太高的问题

  • 也就是更好的完成了解耦
    • MVP 层中,Presenter 还是会持有 View 的引用
    • 但是在 MVVM中,ViewModel进行双向绑定,从而使 viewModel 基本只需要处理业务逻辑,无需关系界面相关的元素了

2. 解决了代码量太多,或者模式化代码太多的问题

由于双向绑定,所以UI相关的代码就少了很多,这也是代码量少的关键。而这其中起到比较关键的组件就是 DataBinding,使所有的 UI 变动都交给了被观察的数据模型

3. 解决了可能会有的内存泄漏问题

MVVM 架构组件中有一个组件是 LiveData它具有生命周期感知能力,可以感知到 Activity 等的生命周期,所以就可以在其关联的生命周期遭到销毁后自行清理,就大大减少了内存泄漏问题

4. 解决了因为Activity停止而导致的View空指针问题

MVVM 中使用了 LiveData,那么在需要更新 View的时候,如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。

也就是他会保证在界面可见的时候才会进行响应,这样就解决了空指针问题。

5. 解决了生命周期管理问题

这主要得益于Lifecycle组件,它使得一些控件可以对生命周期进行观察,就能随时随地进行生命周期事件。

5.2 最后再说说MVVM为什么这么强大?

MVVM 这个架构本身就比较优秀,再加上Google官方的大力支持,出了这么多 Jetpack 的组件,有效缓解了以前 MVVM 八仙过海的各种实现方式。

我觉得就是以下三点优势:

  • 解耦,上手成本更低,方便测试,方便维护
  • 快速开发,消除样板代码
  • 构建高质量的强大应用

优秀的架构思想+官方支持 --> JetPack + MVVM = 强大

参考链接

  • Android框架模式——MVVM
  • 项目架构三问

这篇关于探究 Android MVC、MVP、MVVM 的区别以及优缺点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010446

相关文章

hevc和H.264格式的区别

HEVC(High Efficiency Video Coding)和H.264(也称为Advanced Video Coding,AVC)都是视频压缩标准,但它们之间存在一些显著的区别,主要集中在压缩效率、资源需求和兼容性方面。 压缩效率 HEVC,也被称为H.265,提供了比H.264更高的压缩效率。这意味着在相同的视频质量下,HEVC能够以大约一半的比特率进行编码,从而减少存储空间需求和

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo