MVVM 架构和MVI架构的优缺点对比

Jetpack MVVM 架构讲解

MVVM(Model-View-ViewModel)架构是 Android 开发中一种常用的架构模式,利用 Android Jetpack 组件,可以更简洁和高效地实现 MVVM。以下是 MVVM 的各个组件及其职责:

  1. Model

    • 职责:处理数据逻辑,包括从网络或数据库获取数据。
    • 示例:使用 Room 数据库、网络请求库(如 Retrofit)等来实现数据获取和存储。
  2. View

    • 职责:展示 UI 并响应用户交互。View 直接绑定到 ViewModel,并观察 LiveData 的变化。
    • 示例:Activity、Fragment、XML 布局文件。
  3. ViewModel

    • 职责:为 View 提供数据,处理与 UI 相关的逻辑,确保配置更改(如屏幕旋转)不会丢失数据。
    • 示例:使用 LiveData 来保存数据并通知 View 更新。
示例代码
// Model
@Entity(tableName = "user")
data class User(@PrimaryKey val id: Int,val name: String
)@Dao
interface UserDao {@Query("SELECT * FROM user WHERE id = :userId")fun getUserById(userId: Int): LiveData<User>
}@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}// ViewModel
class UserViewModel(application: Application) : AndroidViewModel(application) {private val userDao: UserDao = AppDatabase.getDatabase(application).userDao()private val _userId = MutableLiveData<Int>()val user: LiveData<User> = Transformations.switchMap(_userId) { id ->userDao.getUserById(id)}fun setUserId(id: Int) {_userId.value = id}
}// View (Activity)
class UserActivity : AppCompatActivity() {private lateinit var userViewModel: UserViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_user)userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)userViewModel.user.observe(this, Observer { user ->// 更新 UIfindViewById<TextView>(R.id.userName).text = user.name})// 设置用户 ID 以触发数据加载userViewModel.setUserId(1)}
}

MVI 架构讲解

MVI(Model-View-Intent)是另一种架构模式,特别强调单一数据流和不可变状态。MVI 的核心思想是通过 Intent 驱动状态变化,并用单一的状态对象来描述整个 UI。

  1. Model

    • 职责:处理数据逻辑,包括从网络或数据库获取数据,类似 MVVM。
  2. View

    • 职责:展示 UI 并响应用户交互,渲染单一的状态对象。
    • 示例:Activity、Fragment、XML 布局文件。
  3. Intent

    • 职责:用户意图的封装,触发状态变化。
    • 示例:点击按钮、输入文本等用户操作。
  4. State

    • 职责:表示 UI 的单一状态。
    • 示例:数据类包含所有 UI 所需的数据。
示例代码
// State
data class UserState(val user: User? = null,val isLoading: Boolean = false,val error: String? = null
)// Intent
sealed class UserIntent {data class LoadUser(val userId: Int) : UserIntent()
}// ViewModel
class UserViewModel : ViewModel() {private val _state = MutableLiveData<UserState>()val state: LiveData<UserState> get() = _statefun processIntent(intent: UserIntent) {when (intent) {is UserIntent.LoadUser -> loadUser(intent.userId)}}private fun loadUser(userId: Int) {_state.value = UserState(isLoading = true)// 假设 repository 获取用户数据repository.getUserById(userId, object : Callback<User> {override fun onSuccess(user: User) {_state.value = UserState(user = user)}override fun onError(error: String) {_state.value = UserState(error = error)}})}
}// View (Activity)
class UserActivity : AppCompatActivity() {private lateinit var userViewModel: UserViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_user)userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)userViewModel.state.observe(this, Observer { state ->// 渲染 UIif (state.isLoading) {// 显示加载中} else if (state.user != null) {findViewById<TextView>(R.id.userName).text = state.user.name} else if (state.error != null) {// 显示错误信息}})// 发送 Intent 加载用户数据userViewModel.processIntent(UserIntent.LoadUser(1))}
}

MVVM 和 MVI 对比

MVVM 的优缺点

优点

  • 简单易理解,易于上手。
  • 更接近传统的 Android 开发模式,使用 Jetpack 组件可以简化开发。
  • ViewModel 与 View 之间通过数据绑定和 LiveData 实现解耦,代码简洁。

缺点

  • 如果没有严格遵守单向数据流,可能导致状态管理混乱。
  • ViewModel 可能会变得复杂,包含过多逻辑。
MVI 的优缺点

优点

  • 强调单一数据流和不可变状态,易于调试和测试。
  • 状态集中管理,UI 只需渲染状态,逻辑清晰。
  • Intent 和 State 的分离,使得代码更加模块化。

缺点

  • 对于简单的应用可能显得过于复杂。
  • 状态对象可能会变得非常庞大,管理起来比较麻烦。
  • 学习曲线较陡,特别是对不熟悉函数式编程和不可变状态的开发者。
总结
  • MVVM 更适合大多数传统的 Android 开发场景,特别是中小型项目,简单易用,结合 Jetpack 组件可以提高开发效率。
  • MVI 更适合复杂的应用,特别是需要严格状态管理和单一数据流的项目,尽管初始学习成本较高,但在维护和扩展上具有优势。

选择哪种架构模式,取决于项目的复杂度、团队的熟悉程度以及具体的需求。综合考虑这些因素,可以做出更适合的架构选择。
联系我

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈AI对生活中文化领域的影响

随着人工智能技术的飞速发展&#xff0c;它已经渗透到我们生活的方方面面&#xff0c;包括文化领域。AI不仅仅是一个技术工具&#xff0c;它正在以前所未有的方式重塑我们的文化景观&#xff0c;影响着我们对艺术、语言、历史和传统的认识与体验。 艺术创作与欣赏 在文化艺术…

反激式开关电源是如何工作的

反激的变压器可以看作一个带变压功能的电感&#xff0c;是一个buck-boost电路。 反击式开关变压器 反激式开关电源是指使用反激高频变压器隔离输入输出回路的开关电源。“反激”指的是在开关管接通的情况下&#xff0c;当输入为高电平时输出线路中串联的电感为放电状态&#x…

ABAP-03基础数据类型

基本数据类型 数据类型默认大小&#xff08;byte&#xff09;有效大小初始值说明示例C11-65535SPACE文本字符&#xff08;串&#xff09;‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…

【PHP小课堂】深入学习PHP中的SESSION(二)

深入学习PHP中的SESSION&#xff08;二&#xff09; 今天的学习内容没有太多的代码&#xff0c;主要还是以理论经验为主&#xff0c;当然&#xff0c;主要的依据还是来源于 PHP 官方文档中的说明。在日常的业务开发中&#xff0c;SESSION 安全一直是我们最主要也是最关心的内容…

算法基础精选题单 动态规划(dp)(递推+线性dp)(个人题解)

前言&#xff1a; 一些简单的dp问题。 正文&#xff1a; 题单&#xff1a;237题】算法基础精选题单_ACM竞赛_ACM/CSP/ICPC/CCPC/比赛经验/题解/资讯_牛客竞赛OJ_牛客网 (nowcoder.com) 递推&#xff1a; NC235911 走楼梯&#xff1a; #include<bits/stdc.h> using na…

在k8s上部署一个简单的应用

部署一个简单的应用 实验目标&#xff1a; 部署一个简单的 web 应用&#xff0c;比如 Nginx 或者一个自定义的 Node.js 应用。 实验步骤&#xff1a; 创建一个 Deployment。创建一个 Service 来暴露应用。验证应用是否可以通过 Service 访问。 今天我们来做一下昨天分享的可…

Debian12的#!bash #!/bin/bash #!/bin/env bash #!/usr/bin/bash #!/usr/bin/env bash

bash脚本开头可写成 #!/bin/bash , #!/bin/env bash , #!/usr/bin/bash , #!/usr/bin/env bash #!/bin/bash , #!/usr/bin/bash#!/bin/env bash , #!/usr/bin/env bash Debian12的 /bin 是 /usr/bin 的软链接, /sbin 是 /usr/sbin 的软链接, (Debian12默认没有ll命令,用的ls …

Python的pandas读取excel文件中的数据

一、前言 hello呀&#xff01;各位铁子们大家好呀&#xff0c;我是一个在软件测试行业摸爬滚打十几年的老江湖了&#xff0c;今天呢来和大家聊一聊用Python的pandas读取excel文件中的数据。 二、读取Excel文件 使用pandas的read_excel()方法&#xff0c;可通过文件路径直接读…

AI音乐时代的挑战与机遇

近期&#xff0c;音乐领域迎来了一波AI大模型的上线潮&#xff0c;这些模型极大地降低了素人生产音乐的门槛&#xff0c;引发了关于音乐圈是否会被AI彻底颠覆的热烈讨论。虽然这一现象带来了短暂的兴奋&#xff0c;但同时也引发了一系列问题&#xff0c;如AI音乐产品的版权归属…

Techviz:XR协作工作流程,重塑远程电话会议新形式

在当今快速发展的数字环境中&#xff0c;无缝远程协作的需求正在成为企业多部门协同工作的重中之重&#xff0c;尤其是对于制造业、建筑和设计等行业的专业人士而言&#xff0c;这一需求更加迫切。传统的远程电话会议协作形式存在着延滞性&#xff0c;已经渐渐跟不上当今快节奏…

动态更新自建的Redis连接池连接数量

/*** 定时更新Redis连接池信息&#xff0c;防止资源让费*/private static final ScheduledThreadPoolExecutor DYNAMICALLY_UPDATE_REDIS_POOL_THREAD new ScheduledThreadPoolExecutor(1, new ThreadFactory() {Overridepublic Thread newThread(Runnable r) {Thread thread …

项目三OpenStack基础环境配置与API使用

任务一 了解OpenStack基础环境配置 1.1 •数据库服务器 1.2 •消息队列服务 •AMQP系统的组成 任务二 了解并使用OpenStack API 2.1 •什么是RESTful API • RESTful API 是目前比较成熟的 一套Internet应用程序的API软件架构 。 • 表现 层&#xff08; Representation …

汽车IVI中控开发入门及进阶(三十一):视频知识扫盲

有效的视频资源管理需要集成许多不同的底层技术,共同为用户提供给定应用程序的最佳体验。其中许多技术是从早期电视广播中使用的技术演变而来的。其他方法,如用于通过网络流式传输视频的压缩方法,相对较新且不断发展。 以下详细概述了与图形和视频处理和传输相关的一些基本…

云上宝库:三大厂商对象存储安全性及差异性比较

前言 看了几家云厂商的对象存储&#xff0c;使用上有相似也有差异&#xff0c;聊聊阿里云、腾讯云、京东云三家对象存储在使用中存在的风险以及防护措施。 0x01 云存储命名 阿里云对象存储OSS(Object Storage Service)&#xff0c;新用户免费试用三个月&#xff0c;存储包容…

安装idea后配置的全局配置

1、打开IDEA应用&#xff1a;Customize→All settings...&#xff0c;如果启动IDEA后&#xff0c;默认打开的是之前的项目&#xff0c;可以关闭当前项目&#xff1a;File→Close Project&#xff0c;就退到全局配置界面了。 2、打开全局配置界面&#xff1a;Editor→File Encod…

FreeRTOS(一)

一.汇编指令 读内存&#xff1a;Load LDR RO&#xff0c;[R1&#xff0c;#4];读地址"R14"&#xff0c;得到的4字节数据存入RO 写内存&#xff1a;Store STR RO&#xff0c;[R1&#xff0c;#4]:把R0的4字节数据写入地址"R14" 加减 ADD RO.R1&#xff0c;R2R…

torch.topk用法

torch.topk用法 介绍使用示例 介绍 官网介绍&#xff1a;https://pytorch.org/docs/stable/generated/torch.topk.html 在指定维度选取k个最大&#xff08;最小&#xff09;的值。 使用示例 values torch.tensor([[2, 1, 3], [1, 2, 3]]) # values # tensor([[2, 1, 3], #…

项目拆分 多模块原则

多模块拆分的必要性 使用Java技术开发的工程项目&#xff0c;无论是数据处理系统还是Web网站&#xff0c;随着项目的不断发展&#xff0c;需求的不断细化与添加&#xff0c;工程项目中的代码越来越多&#xff0c;包结构也越来越复杂这时候工程的进展就会遇到各种问题&#xff…

斯巴达(Spartanhost)VPS的性能评测

原创原文链接&#xff1a;详细斯巴达&#xff08;Spartanhost&#xff09;VPS的性能和购买价值评测 | BOBO Blog (soulcloser.com)https://www.soulcloser.com/3398/ 引言 最近看了全球的VPS商家&#xff0c;想搞台网站高性能的服务器&#xff0c;发现一个特别有意思的商家竟…

Mathtype7永久无限免费安装包下载地址2024最新方法步骤

亲爱的数学爱好者们&#xff0c;今天我要分享一个让数学表达变得超级简单的神器——Mathtype7最新破解版&#xff01;&#x1f389; 这不仅仅是个软件&#xff0c;而是打开高效学习和工作的钥匙。准备好了吗&#xff1f;让我们一起探索这个神奇的工具&#xff01; MathType最新…