Android 架构MVI、MVVM、MVC、MVP

2024-02-29 04:44
文章标签 android 架构 mvc mvp mvvm mvi

本文主要是介绍Android 架构MVI、MVVM、MVC、MVP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、MVC(Model-View-Controller)

二、 MVP(Model-View-Presenter)

三. MVVM(Model-View-ViewModel)

四. MVI(Model-View-Intent)

五.MVI简单实现


先简单了解一下MVC、MVP和MVVM。

一、MVC(Model-View-Controller)

模型-视图-控制器
MVC的目的就是为了M和V代码分离,降低耦合性。

Model:数据来源,网络请求数据和数据库数据。
View:对应xml布局文件和动态的布局部分。
Controller:逻辑控制部分。主要起到协调M层和V层的关系,起承上启下的作用。

优点:

一定程度上实现了代码分离,降低代码的耦合性。


缺点:

1.Controller和View层难以完全解耦,而且随着业务逻辑增多

2.Controller会变的越来越臃肿。在Android中Activity充当Controller的角色,后面Activity会变成GadActivity。

3. M层和V层还有交互,没有做到完全分离。

二、 MVP(Model-View-Presenter)

模型-视图-提供者
MVP是在MVC的基础上发展过来的,实现了M层和V层的完全分离,进一步代码解耦。

Model:数据来源,网络请求数据和数据库数据。
View:对应xml布局文件和动态的布局部分。对应Activity。
Presenter:逻辑控制部分。通过接口连接M层和V层。

优点:

1.V层对应Activity,只负责UI的展示和P层直接通信,和M层没有任何交互。
2.V层没有和M层有交互,可以抽成单独的组件,方便复用。
3.代码结构清晰,P层可以用于多个视图,而不需要改变P层的逻辑。
4.V层和M层完全分离,方便协同工作,只需要专注做视图或者逻辑控制部分,不用关系对方的逻辑。比如负责逻辑控制部分不用等设计出图,就可以直接写代码,并进行单元测试。
5.代码复用率高,方便单元测试。


缺点:

1.M层和V层都需要和P层进行通许,会导致P层代码很复杂,而且都是通过接口通讯,如果一个P层用于多个Activity,所有Activity都要实现全部都接口,无论能不能用得到。修改P层接口,往往会涉及到很多个界面,很麻烦。
2.P层和V层通过接口通讯,会持有View的引用,容易造成内存泄露。
3.随着业务增多,P层即使只对应一个视图,接口也会越来越多。

三. MVVM(Model-View-ViewModel)

模型-视图-视图模型
MVVM在MVP的基础上进一步解耦,VM层不在持有View的引用。
引入响应式编程、Lifecycle生命周期感知、LiveData数据存储、DataBinding数据绑定概念。配合Goole提供的Jetpack组件能节省很多代码。

Model:数据来源,网络请求数据和数据库数据。
View:对应xml布局文件和动态的布局部分。对应Activity。向比较MVP这里的View是通过DataBinding来进行双向绑定数据。
ViewModel:逻辑控制部分。作为桥梁,通知M层处理数据,并将结果回调到V层处理UI。Activity持有ViewModel引用,ViewModel不持有View的引用。

优点:

1.进一步解耦,ViewModel不持有View的引用,当V层改遍,只要V层绑定的数据不变,ViewModel就不需要修改。
2.不需要写很多样板代码,省略findViewById(),Activity变得很简介。
3.通过DataBinding实现View和Model的实时改变,一方改变就会同步到对方。


缺点:

1.DataBinding双向绑定采用异步更新数据,对ListView这样的列表,效率比较低。而且在实际开发中,设计出的Ui效果比较复杂,数据绑定不能完全实现,往往只使用到DataBinding一半的功能,数据更新部分还是手动实现。
2.DataBinding会自动生成大量的代码和属性字段。
3.复杂的页面要定义多个LiveData,并且都要暴露为不可变的LiveData。
4.LiveData是粘性事件,数据倒灌等问题。解决方法:使用第三方 UnPeekLiveData

四. MVI(Model-View-Intent)

模型-视图-意图
出现的目的是为了解决MVVM中双向绑定数据的不足。把双向绑定变成单向数据流。使用Flow代替LiveData存储数据。

Model:这里的Model不是其他框架中的Model层,在MVI框架中表示存储UI的状态。
View:在MVI中View层主要是接口,负责相应UI的状态。
Intent:在MVI中Intent(和Android中的Intent不是同一个)主要负责传递UI状态。使用sealed关键字,形成一个封闭类,类似枚举。主要用于V层通知ViewModel处理数据。
State:和Intent一样是一个封闭类,主要用于ViewModel回调数据修改UI。

优点:

1.UI的所有变化来自State,所以只需聚焦State,架构更简单、易于调试
2.数据单向流动,很容易对状态变化进行跟踪和回溯
3.State实例都是不可变的,确保线程安全
4.UI只是反应State的变化,没有额外逻辑,可以被轻松替换或复用

缺点:

1.所有的操作最终都会转换成State,所以当复杂页面的State容易膨胀
2.State是不变的,每当State需要更新时都要创建新对象替代老对象,这会带来一定内存开销

五、总结

mvc:activity即是v也是c,代码臃肿
mvp:接口太多,p层容易内存泄漏
mvvm:databinding生成的代码态度,livedata数据倒灌/粘性
mvi:复杂页面,state膨胀

非常小的项目用MVC


六.MVI简单实现

1.MVI

mvi的改动在于将View和ViewModel之间的多数据流改为基于ViewState的单数据流。

MVI分为四个部分:

  • View: Activity 和xml文件,与其他模式中的View的概念相同。
  • Intent: 定义数据操作,将数据传到Model的唯一来源。
  • ViewModel: 存储视图状态,负责处理表现逻辑,并将ViewState设置给可观察数据容器
  • ViewState: 一个数据类,包含页面状态和对应的数据。

2.MVI特点

唯一可信源:数据只有一个来源(ViewModel),与MVVM思想相同
单向数据流:状态向下流动,事件向上流动。
响应式:ViewState包含页面当前状态和数据,View通过订阅
ViewState就可以完成页面刷新。相比于 MVVM 是新的特性。

3.单向数据流

界面变化是数据流的末端,界面消费上游产生的数据,并随上游数据的变化进行刷新。

状态向下流动,事件向上流动的这种模式称为单向数据流

MVI强调数据的单向流动,主要分为几步:

  1. 用户操作以Intent的形式通知Model.
  2. Model基于Intent更新State
  3. View接收到State变化刷新UI

数据永远在一个环形结构中单向流动,不能反向流动。

4.缺点:

  • State 膨胀: 所有视图变化都转换为 ViewState,还需要管理不同状态下对应的数据。实践中应该根据状态之间的关联程度来决定使用单流还是多流;
  • 内存开销: ViewState 是不可变类,状态变更时需要创建新的对象,存在一定内存开销;
  • 局部刷新: View 根据 ViewState 响应,不易实现局部 Diff 刷新,可以使用 Flow#distinctUntilChanged() 来刷新来减少不必要的刷新。

 

这篇关于Android 架构MVI、MVVM、MVC、MVP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/757609

相关文章

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l