MVC和MVVM设计模式中对应的是什么组件?有什么对应关系?

MVC(Model-View-Controller)MVVM(Model-View-ViewModel) 都是客户端/前端开发中非常经典的架构设计模式。在 Android 开发的演进历史中,MVC 是早期的主流,而 MVVM 是目前 Google 官方主推(基于 Jetpack 组件)的现代架构。

MVVM 本质上是 MVC 的一次进化。它们的核心目的都是为了**"解耦"**(将数据、业务逻辑与 UI 展示分离开来)。

以下是它们的组件对应关系和核心差异的详细拆解:


1. 组件对应关系

从宏观上看,MVC 和 MVVM 的组件对应关系如下:

|----------------------|-------------------------|----------------------------------------------------------------------------------|-----------------------------------------------------------------|
| MVC 模式 | 对应到 MVVM 模式 | 它们在架构中的职责 | Android 中的具体表现 |
| Model (模型) | ➡️ Model (模型) | 核心数据与业务逻辑。<br>负责获取、存储、处理数据。不关心 UI 如何展示。 | 数据库 (Room)、网络请求 (Retrofit)、数据仓库 (Repository) 等。 |
| View (视图) | ➡️ View (视图) | 界面的展示与用户交互。<br>负责把内容画出来,并接收用户的点击、滑动等操作。 | XML 布局文件、Activity、Fragment、Compose UI 组件。 |
| Controller (控制器) | ➡️ ViewModel (视图模型) | 中间人/大脑。<br>连接 View 和 Model,处理 View 传来的用户操作,向 Model 请求数据,并将数据加工后交给 View 显示。 | MVC 中通常是 Activity/Fragment。<br>MVVM 中是 Jetpack 的 ViewModel 类。 |


2. Controller 和 ViewModel 的本质区别 (核心考点)

虽然 Controller 演变成了 ViewModel,但它们的工作方式发生了巨大的思维范式转变。这也是 MVVM 优于 MVC 的核心原因。

在 MVC 中:Controller 是"独裁者"(命令式)
  • 持有引用:Controller 直接持有 View 的引用(比如 TextView tvName)。

  • 工作流:用户点击按钮 -> Controller 接收事件 -> 请求 Model 数据 -> 数据返回后,Controller 直接调用 tvName.setText("张三") 来更新 UI。

  • 痛点:在 Android 中,Activity 同时充当了 View 和 Controller 的角色。随着业务增加,Activity 变得极其臃肿(俗称 Massive View Controller),且极难编写单元测试(因为逻辑和 UI 控件强绑定)。

在 MVVM 中:ViewModel 是"广播站"(响应式/观察者模式)
  • 双向隔离 :ViewModel 绝对不持有任何 View(UI 控件)的引用。它根本不知道是谁在显示它的数据。

  • 工作流

    1. ViewModel 内部维护一份"状态数据"(比如 val name = MutableStateFlow("张三"))。

    2. View 提前**订阅(Observe)**这个状态数据。

    3. 用户点击按钮 -> View 通知 ViewModel 去获取数据。

    4. ViewModel 拿到数据后,仅仅是把内部的 name 更新为 "李四"。

    5. View 因为一直监听着 name,自动察觉到变化,UI 自己刷新了文字。

  • 优势:UI 和逻辑彻底解耦。ViewModel 变成了纯粹的 Java/Kotlin 代码,极其容易测试;并且完美契合了 Android 的生命周期(配置更改如屏幕旋转时,ViewModel 数据不会丢失)。


3. 具体对应关系与示例(以 Android 为例)

假设我们要实现一个"输入账号密码,点击登录"的功能:

【过去:MVC 时代的写法】
  • View & Controller (混合体):LoginActivity.kt

    • 包含 UI 控件:EditText, Button。

    • 同时包含控制逻辑:监听 Button 点击,调用网络请求,判断成功后 Toast.show 或者跳转页面。

  • Model:AuthManager.kt(负责实际发起 HTTP 请求)。

痛点:LoginActivity 代码上千行,如果改了界面的某个按钮,经常容易引发空指针异常。

【现在:MVVM 时代的写法】
  • View:LoginActivity.kt 或 LoginScreen.kt (Compose)

    • 只负责:把输入框的内容发给 ViewModel,观察 ViewModel 的状态(Loading 还是 Success),然后根据状态展示转圈动画或跳转页面。
  • ViewModel:LoginViewModel.kt

    • 只负责 :接收传入的账号密码,调用 Repository 发起请求,然后把一个表示状态的变量(比如 UiState)改为 Loading,请求结束改为 Success。没有任何 Android 相关的 import
  • Model:UserRepository.kt (结合 Retrofit)。


总结

  • Model 没有变:无论 MVC 还是 MVVM,底层的数据获取和存储逻辑都是相对独立的。

  • View 更纯粹了:在 MVVM 中,View 被剥夺了业务决策权,退化为一个纯粹的"状态展示机"。

  • Controller 进化成了 ViewModel :从**"主动命令 View 做事情 (Controller)",变成了 "我只管准备好数据,View 你自己看着办 (ViewModel)"。底层支撑这一变化的技术是 数据绑定(DataBinding)响应式流(LiveData / StateFlow / Compose State)**。

相关推荐
tobias.b14 小时前
软件设计模式:核心术语·名词解释·关联对比
设计模式
hnlgzb19 小时前
目前编写安卓app的话有哪几种设计模式?
android·设计模式·kotlin·android jetpack·compose
zs宝来了19 小时前
Spring MVC 请求处理全流程:从 DispatcherServlet 到视图渲染
spring·mvc·源码解析·dispatcherservlet
pedestrian_h20 小时前
Java单例模式回顾
java·单例模式·设计模式
饼干哥哥20 小时前
这10个n8n工作流,直接干死了90%的Tiktok视频生产,一键直出100条
设计模式
砍光二叉树21 小时前
【设计模式】行为型-命令模式
设计模式·命令模式
程序员小寒21 小时前
JavaScript设计模式(六):职责链模式实现与应用
java·javascript·设计模式
无籽西瓜a1 天前
【西瓜带你学设计模式 | 第五期 - 建造者模式】建造者模式 —— 产品构建实现、优缺点与适用场景及模式区别
java·后端·设计模式·软件工程·建造者模式
木斯佳1 天前
前端八股文面经大全:字节跳动前端一面·深度解析(Plus Ultra版)(2026-03-30)·面经深度解析
前端·设计模式·八股·光栅化