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

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

这个问题其实很有意思,而且很多 Android 开发者第一次接触 Android Jetpack 的 Android 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--Controller 或 Model--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 name,birthYear 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:普通数据类 → 只是存数据,没有业务含义
相关推荐
AlfredZhao2 个月前
知识库文件解析失败:一次由 Domain Index 引发的定位记录
index·domain
AlfredZhao3 个月前
一篇搞定:用 curl 测试私有部署模型联通性
llm·embedding·model·curl
曲幽6 个月前
FastAPI + Pydantic 模型终极实战手册:从能跑就行到固若金汤,这些技巧你一定用得上
python·fastapi·web·model·field·pydantic·validator·basemodel
曲幽8 个月前
FastAPI + Ollama 实战:搭一个能查天气的AI助手
python·ai·lora·torch·fastapi·web·model·ollama·weatherapi
消失的旧时光-19438 个月前
第二十二课:领域建模入门——从业务中“提炼结构”(认知篇)
java·spring boot·后端·domain
十五年专注C++开发8 个月前
QStyleItemDelegate:自定义列表控件类神器
qt·model·view·delegate
JiMoKuangXiangQu9 个月前
Linux 内存 domain 管理
linux·内存管理·domain
消失的旧时光-19439 个月前
Freezed + json_serializable:DTO / Domain 分层与不可变模型(入门到落地)-----上篇
flutter·json·dto·domain
曲幽10 个月前
Flask项目目录结构指南:从单文件到模块化
python·web·model·route·项目结构