如何理解 ViewModel 中的Model,为什么要叫ViewModel而不是其它的名字?

这个问题其实很有意思,而且很多 Android 开发者第一次接触 Android JetpackAndroid ViewModel 时都会问:

为什么叫 ViewModel
为什么不是 ViewController / Presenter / DataHolder

关键就在 “Model” 这个词


一、先理解 MVC / MVVM 里的 Model

在经典架构里,比如 Model–View–ViewModel

View
Model
ViewModel

各自含义:

角色 作用
View UI(Activity / Fragment / Compose UI)
Model 业务数据(Repository / Entity / Database)
ViewModel 给 View 准备数据的模型

重点:

ViewModel 是 “View 的数据模型”

所以它叫:

View + Model

而不是普通的 Model。


二、为什么叫 “View 的 Model”

举个最简单例子。

假设 UI 要显示用户信息:

User name
User age
User avatar

真实数据可能来自:

Network API
Database
Cache

这些属于 业务 Model

但 UI 实际需要的数据可能是:

UserNameText
AvatarUrl
IsVip
IsLoading
ErrorMessage

这些数据:

不是业务模型
而是 UI 状态

于是就需要一个 View 的模型

data class UserUiState(
    val name: String,
    val avatar: String,
    val isLoading: Boolean
)

这就是 ViewModel 提供的数据


三、ViewModel 的本质

可以把 Android ViewModel 理解为:

UI State Holder

或者:

View 的数据容器

它负责:

获取数据
处理逻辑
提供 UI 状态

但:

不直接操作 UI

四、为什么不叫 Controller

早期 Android 其实更像 Model–View–Controller

Activity = Controller

问题是:

Activity 变成:

God Class

里面全是:

网络请求
数据库
UI
业务逻辑

代码会变成:

2000+ 行

于是 Google 推了 MVVM


五、为什么不用 Presenter(MVP)

另一种架构是 Model–View–Presenter

View
Presenter
Model

Presenter 负责:

更新 View

但 MVP 有个问题:

Presenter 持有 View

例如:

view.showLoading()

这样:

Presenter 和 View 强耦合

ViewModel 不知道 View 的存在


六、ViewModel 的核心特点

ViewModel 只做一件事:

提供数据

例如:

class UserViewModel : ViewModel() {

    val userName = MutableLiveData<String>()

}

View 只负责观察:

viewModel.userName.observe(this) {
    textView.text = it
}

所以:

ViewModel 不控制 UI
只提供 UI 数据

七、Android 为什么特别需要 ViewModel

Android 有个大问题:

配置变化(configuration change)

例如:

旋转屏幕
切换深色模式
语言变化

Activity 会:

destroy
recreate

如果数据在 Activity:

数据丢失
重新请求网络

Android ViewModel 会:

跨配置变化保存数据

生命周期:

Activity 重建
ViewModel 不重建

所以它特别适合存 UI 数据。


八、一个直观理解

可以把 ViewModel 想象成:

View 的后台秘书

流程:

UI(View)
   ↓
ViewModel
   ↓
Repository
   ↓
Network / Database

ViewModel 把复杂数据整理好,再交给 UI。


九、为什么这个名字其实很准确

ViewModel 的含义其实是:

Model for View

也就是:

专门为 View 准备的数据模型

所以不是:

业务 Model

而是:

UI Model

十、一句话理解

最简单理解:

ViewModel = View 的数据模型

或者:

ViewModel = UI 状态管理器

💡 一个很多 Android 开发者后来才意识到的事情:

在现代 Android 架构里:

ViewModel 才是真正的 UI 逻辑层

而:

Activity / Fragment
其实只是 UI 容器

Model是表示什么意思?数据模型吗?那为什么叫Model,而不叫Data Model?

这个问题问得非常好 👍,其实涉及 软件架构里 “Model” 这个词的历史含义。很多人第一次看到 Model–View–ControllerModel–View–ViewModel 时都会以为:

Model = Data Model(数据模型)

但实际上 Model 的含义比“数据”更广


一、Model 的本意是什么

Model 在英语里的意思是:

对现实世界某个事物的抽象表示

例如:

现实世界 模型
用户 User 类
订单 Order 类
汽车 Car 类

所以:

Model = 对系统数据 + 业务规则 的抽象

它通常包含:

数据
业务逻辑
状态
规则

而不只是数据。


二、为什么不叫 Data Model

如果叫 Data Model,含义就会变成:

只表示数据结构

例如:

data class User(
    val name: String,
    val age: Int
)

这只是:

数据结构

但真实系统里的 Model 可能还有逻辑:

class BankAccount(
    var balance: Double
) {

    fun withdraw(amount: Double) {
        if (amount > balance) {
            throw Exception("Insufficient balance")
        }
        balance -= amount
    }

}

这里:

balance 是数据
withdraw 是业务逻辑

整个对象才是 Model


三、MVC 里的 Model 含义

Model–View–Controller 里:

Model
View
Controller

含义是:

作用
Model 业务数据 + 业务规则
View UI
Controller 协调逻辑

所以:

Model ≠ 仅仅数据

而是:

系统的业务表示

四、Android 里的 Model

在 Android 现代架构中:

View
ViewModel
Repository
DataSource

通常:

Model 层

包括:

Repository
Database
Network
Entity
Domain logic

例如:

User
UserRepository
UserDao
UserApi

这些都属于 Model 层


五、为什么叫 ViewModel

理解了 Model 之后就容易理解 Android ViewModel

ViewModel

其实就是:

Model for the View

也就是:

给 View 用的模型

它描述的是:

UI 状态
UI 数据

而不是:

业务数据

例如:

data class LoginUiState(
    val username: String,
    val password: String,
    val isLoading: Boolean,
    val errorMessage: String?
)

这就是:

View 的 Model

所以叫:

ViewModel

六、一个简单类比

假设你做一个电商 App。

现实世界:

商品
价格
库存
订单

系统里:

Product (Model)
Order (Model)

但 UI 页面需要的是:

ProductNameText
PriceText
IsInStock
IsLoading

于是:

ProductViewModel

专门给 UI 用。


七、一句话总结

最准确理解:

Model = 对业务世界的抽象表示

它可能包含:

数据
规则
行为
状态

而:

Data Model

只是:

数据结构

八、一个很多人不知道的小知识

Model 这个词在 MVC 中诞生于 1970 年代,最早来自 Smalltalk GUI 系统。

后来所有架构:

  • Model–View–Controller
  • Model–View–Presenter
  • Model–View–ViewModel

都沿用了这个词。

所以今天我们仍然用:

Model

而不是:

Data Model

分层中的Domain层又是什么意思?如何理解 这个Domain

Domain 这个词在软件架构里其实非常关键,但也最容易让人困惑。先给你一句最核心的理解:

Domain = 业务领域(Business Domain)

也就是说:

Domain 层 = 表达业务规则的那一层

不是 UI,也不是数据库,而是 系统真正的业务逻辑所在的地方

这个概念来自 Domain-Driven Design(DDD)。


一、Domain 的字面意思

英文 Domain 原本意思是:

领域
范围
业务世界

例如:

系统 Domain
电商系统 商品、订单、支付
银行系统 账户、转账、余额
社交系统

分层中的Domain层又是什么意思?如何理解 这个Domain,它的单词含义有哪些,以及在分层时又表示什么?

这个问题其实触到了软件架构里的一个核心概念:Domain(领域)。我们可以从 单词本义 → 软件架构含义 → 分层中的作用 → 具体例子 一步步理解。


一、Domain 这个单词本身是什么意思

Domain 在英语里常见含义有:

含义 解释 例子
领域 / 范围 某一类事物的范围 science domain
领域知识 某个专业领域的知识 business domain
统治范围 管辖的区域 kingdom domain
计算机领域 系统关注的问题空间 problem domain

在软件工程里,Domain 通常指:

系统所要解决的业务领域(Business Domain)

例如:

系统 Domain
电商系统 商品、订单、支付
银行系统 账户、余额、转账
社交系统 用户、关注、消息

这些就是系统的 业务世界


二、Domain 在软件架构里的含义

在软件架构中,Domain 指的是:

业务规则 + 业务概念

也就是说:

系统真正要解决的问题

例如一个银行系统:

开户
转账
余额
利息计算

这些都属于 Domain 逻辑

它们不是:

UI
数据库
网络请求

而是:

业务规则

三、Domain 层在分层架构中的位置

在现代架构中(例如 Android 常见架构),通常会看到三层:

Presentation
Domain
Data

关系如下:

UI / Activity / ViewModel
          │
          ▼
      Domain Layer
          │
          ▼
     Data Layer

含义:

作用
Presentation UI 展示
Domain 业务逻辑
Data 数据来源

四、三层分别做什么

1️⃣ Presentation(展示层)

负责:

UI
用户交互
状态展示

例如:

  • Activity
  • Fragment
  • Compose UI
  • ViewModel

2️⃣ Domain(领域层)

负责:

业务规则
业务流程
用例逻辑

常见组件:

UseCase
Interactor
Domain Model

例如:

TransferMoneyUseCase
LoginUseCase
GetUserProfileUseCase

3️⃣ Data(数据层)

负责:

网络
数据库
缓存
Repository

例如:

Retrofit API
Room DAO
Repository

五、一个具体例子(电商系统)

假设一个 下单功能

Presentation 层

UI 调用:

viewModel.placeOrder()

Domain 层

业务逻辑:

class PlaceOrderUseCase(
    private val orderRepository: OrderRepository
) {

    suspend fun execute(order: Order) {

        if (order.items.isEmpty()) {
            throw Exception("订单不能为空")
        }

        orderRepository.save(order)
    }
}

这里的规则:

订单不能为空

就是 Domain 规则


Data 层

负责真正保存数据:

class OrderRepositoryImpl(
    private val api: OrderApi,
    private val dao: OrderDao
) : OrderRepository {

    override suspend fun save(order: Order) {
        api.createOrder(order)
    }

}

六、为什么要有 Domain 层

如果没有 Domain 层:

Activity
  ↓
Repository
  ↓
Network

问题:

业务逻辑散落在 UI
难测试
难维护

有了 Domain 层:

UI
 ↓
UseCase
 ↓
Repository

好处:

业务逻辑集中
容易测试
结构清晰

七、Domain 层通常包含什么

在很多架构中,Domain 层会包含:

组件 作用
Entity 业务实体
UseCase 业务用例
Repository Interface 数据接口
Domain Service 复杂业务逻辑

八、Android 常见的分层结构

很多 Android 项目结构是:

presentation
   ├─ ui
   └─ viewmodel

domain
   ├─ model
   └─ usecase

data
   ├─ repository
   ├─ network
   └─ database

依赖方向:

presentation → domain → data

九、一句话理解 Domain

最简单理解:

Domain = 业务世界

Domain 层就是:

表达业务规则的一层

十、为什么很多项目不写 Domain 层

在小项目中经常简化为:

ViewModel
   ↓
Repository

原因:

业务逻辑简单

但大型项目(几十万行代码)通常会加入 Domain 层。


总结

Domain 的含义:

1️⃣ 单词本义

领域 / 范围

2️⃣ 软件架构中

业务领域

3️⃣ 分层架构中

负责业务规则的一层

所以:

Domain Layer = 业务逻辑层

Entity、DTO、VO、Domain Model 到底有什么区别?还有Entity与JavaBean又有什么不同?

这几个概念在分层架构里容易混淆,但实际上它们的作用和语境是不一样的。我给你整理一个清晰的对比表和说明,让你一眼就能分清。


一、Entity(实体)

定义
Entity 表示 数据库或持久化层的表结构的映射对象,或者说是系统中可唯一标识的一类对象(有主键)。它通常包含业务数据,是 Domain 的一部分

特点

特性 说明
有唯一标识 通常有主键(如 id)
持久化对象 与数据库表或存储对应
可包含业务逻辑 简单的规则可以放,但尽量少

示例(Kotlin + Room):

@Entity(tableName = "users")
data class UserEntity(
    @PrimaryKey val id: Long,
    val name: String,
    val age: Int
)

注意:这里是数据库表映射对象。


二、DTO(Data Transfer Object,数据传输对象)

定义
DTO 是 用于在不同系统或层之间传输数据的对象,通常是网络 API 返回或请求的数据格式。

特点

特性 说明
传输专用 通常和数据库结构无关,和接口约定一致
只含数据 一般不含业务逻辑
可序列化 可以转 JSON、ProtoBuf 等

示例(网络 API 返回):

data class UserDto(
    val id: Long,
    val fullName: String,
    val birthYear: Int
)

注意:字段可能和数据库不完全一致,例如 fullName vs namebirthYear vs age


三、VO(Value Object,值对象)

定义
VO 表示 不可变的值对象,它的身份由内部值决定,而不是引用。常用于 业务逻辑层 Domain 中。

特点

特性 说明
不可变 一般只读,不提供 setter
无唯一标识 两个值相同就认为相等
承载业务意义 用于描述业务概念(金额、坐标、邮箱等)

示例

data class Email(val value: String) {
    init {
        require(value.contains("@")) { "Invalid email" }
    }
}

两个 Email(“a@b.com”) = Email(“a@b.com”) 是相等的。


四、Domain Model(领域模型)

定义
Domain Model 表示 业务领域中的核心概念及业务规则
可以包含 Entity + VO + 业务逻辑,是 Domain 层的核心

特点

特性 说明
包含业务逻辑 用 UseCase 操作,或者内部方法
可能组合 VO / Entity Domain Model 不等于 Entity,但可以用 Entity 表示
纯粹面向业务 与 UI、数据库无关

示例

data class Order(
    val id: Long,
    val items: List<OrderItem>,
    val totalAmount: Money
) {
    fun addItem(item: OrderItem): Order {
        return copy(items = items + item)
    }
}

这里的 Order 是 业务概念,可以用 DTO 或 Entity 数据填充,但逻辑在这里处理。


五、Entity 与 JavaBean 的区别

很多初学者把 Entity = JavaBean,其实不完全对。

特性 Entity JavaBean
用途 持久化(数据库表) 通用数据对象(可用于 UI、数据交换等)
唯一标识 通常有主键 没有要求
业务逻辑 可以有部分业务规则 一般只存数据,没有业务逻辑
持久化注解 有(Room、JPA)
可变性 可变或不可变 一般可变,get/set 方法

简单理解:

  • Entity 是业务持久化的 JavaBean
  • JavaBean 更宽泛,只是一种标准的 POJO 数据对象

六、总结

概念 作用 是否包含业务逻辑
Entity Data / Domain 持久化对象 少量或无
DTO Data / Network 传输对象
VO Domain 值对象(业务概念) 可能有验证逻辑
Domain Model Domain 核心业务模型
JavaBean 任意 通用数据对象 一般无

七、简单比喻

以电商系统为例:

  • DTO:接口返回 JSON → UserDto
  • Entity:数据库表 → UserEntity
  • VO:邮箱、价格等小业务对象 → Email, Money
  • Domain Model:业务逻辑对象 → User / Order
  • JavaBean:普通数据类 → 只是存数据,没有业务含义
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐