编程中的Model、Domain、Entity等的含义

如何理解 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:普通数据类 → 只是存数据,没有业务含义
相关推荐
曲幽13 天前
FastAPI + Ollama 实战:搭一个能查天气的AI助手
python·ai·lora·torch·fastapi·web·model·ollama·weatherapi
消失的旧时光-19431 个月前
第二十二课:领域建模入门——从业务中“提炼结构”(认知篇)
java·spring boot·后端·domain
十五年专注C++开发1 个月前
QStyleItemDelegate:自定义列表控件类神器
qt·model·view·delegate
JiMoKuangXiangQu2 个月前
Linux 内存 domain 管理
linux·内存管理·domain
消失的旧时光-19432 个月前
Freezed + json_serializable:DTO / Domain 分层与不可变模型(入门到落地)-----上篇
flutter·json·dto·domain
曲幽3 个月前
Flask项目目录结构指南:从单文件到模块化
python·web·model·route·项目结构
Par@ish3 个月前
【局域网协议】为什么我们需要管理DNS?
安全·dns·domain
core5123 个月前
实战:用 Spring Boot 搭建 Model Context Protocol (MCP) 服务
java·spring boot·后端·model·模型·mcp
依旧风轻9 个月前
Domain 层完全指南(面向 iOS 开发者)
ios·domain·entity·sqi