后端各层是否都要有数据 Bean?——一次把 DTO / Command / Entity / PO 的边界讲清楚
摘要:后端架构设计中,数据对象分层是核心原则。系统应划分为接口层(DTO/VO)、应用层(Command/Query)、领域层(Entity)和基础设施层(PO),各层维护专属数据模型。关键是通过转换器(Assembler/Mapper)实现跨层数据流转,避免对象污染。这种分层设计能将业务变化、接口变化和存储变化隔离在特定层级,保障系统长期可维护性。典型架构问题包括Controller直接使用En
学后端到一定阶段,几乎每个人都会产生一个困惑:
👉 为什么项目里有这么多“Bean”?
👉 DTO、VO、Entity、PO、Command 到底是不是多此一举?
👉 能不能一个 User 从 Controller 直接用到数据库?这个问题,本质不是“类太多”,而是:
👉 你有没有开始做“系统边界设计”。
这篇文章,专门讲一件事:
👉 后端各层到底要不要有自己的数据 Bean?它们各自代表什么?
一、先给结论:各层一定都会有 Bean,而且必须有
结论很明确:
👉 后端每一层,都会有自己的数据对象(Bean / Model / Object)。
👉 真正的架构能力,不是“少建类”,而是:
❗ 不让同一个对象,跨层乱跑。
一个干净的后端系统里,至少存在四类不同语义的对象:
- 接口对象
- 用例对象
- 领域对象
- 持久化对象
它们解决的是完全不同的问题。
二、后端四层,对应四种“数据模型”
现代后端工程,本质可以拆成四层:
Interface(接口层)
Application(应用层)
Domain(领域层)
Infrastructure(基础设施层)
每一层,都会有“属于自己的数据模型”。
1️⃣ Interface 层:协议模型(DTO / VO)
这一层的对象,本质是:
👉 协议数据结构
它解决的问题是:
- HTTP / RPC 怎么传数据
- 前端 / 调用方怎么理解接口
典型对象:
- RequestDTO
- ResponseDTO
- VO
例如:
CreateUserRequestDTO
UserDetailVO
特点:
- 面向接口
- 字段贴近页面/接口
- 可能很扁平
- 经常随接口变化
👉 它们不是业务模型,而是通信模型。
2️⃣ Application 层:用例模型(Command / Query / Context)
这一层的对象,本质是:
👉 “系统要做什么事”的表达
它解决的问题是:
- 一个用例需要哪些信息
- 一个流程如何被驱动
- 一个业务操作的上下文
典型对象:
CreateUserCommand
UserRegisterContext
UserPageQuery
特点:
- 面向“动作”
- 服务于流程编排
- 常作为 Service 入参
- 生命周期通常只存在一次调用中
👉 它们是用例驱动模型,不是业务真相。
3️⃣ Domain 层:业务模型(Entity / VO / Aggregate)
这是后端系统最核心的一层。
这一层的对象,本质是:
👉 业务本身
它解决的问题是:
- 业务规则
- 状态变化
- 不变量约束
- 行为封装
典型对象:
User
Account
Order
Money
特点:
- 有行为,不只是 get/set
- 不依赖框架
- 不关心 HTTP
- 可纯 Java 单测
👉 它们是系统里最值钱的代码。
4️⃣ Infrastructure 层:持久化/技术模型(PO / DO)
这一层的对象,本质是:
👉 技术实现模型
它解决的问题是:
- 表怎么存
- 字段怎么映射
- 中间件怎么对接
典型对象:
UserPO
AccountDO
UserRecord
特点:
- 强贴合表结构
- 可能有 ORM 注解
- 为数据库/中间件服务
- 可以很“丑”
👉 它们不是业务模型,是存储与技术模型。
三、层与层之间,数据是如何流动的?
核心原则只有一句:
👉 跨层,必须转换。
典型链路:
HTTP Request
↓
RequestDTO
↓ Assembler
Command
↓
Domain Entity
↓
Repository
↓
PO / DO
↓
Database
返回路径:
PO → Entity → VO
👉 中间的转换层,通常叫:
- Assembler
- Mapper
- Converter
- MapStruct
它的存在意义只有一个:
👉 保证对象不跨层污染。
四、三个最典型的“架构崩坏信号”
如果你项目里出现这些情况,说明边界已经开始塌了:
❌ Controller 直接使用 Entity
❌ Domain 对象带 JPA / MyBatis 注解
❌ Repository 返回 PO 给 Controller
这些问题短期不一定炸,
但系统一复杂,几乎必然失控。
五、一个非常好用的判断方法
你拿到一个对象,问自己一句话:
👉 “这个对象,表达的是业务事实、流程事实、协议事实,还是技术事实?”
- 业务事实 → Domain
- 流程事实 → Application
- 协议事实 → Interface
- 技术事实 → Infrastructure
👉 放错层,本质就是语义错位。
六、最小后端服务中,推荐出现的 Bean 清单
以“最小后端服务”为例,一个结构清晰的工程,至少应该看到:
Interface
- CreateUserRequestDTO
- UserVO
Application
- CreateUserCommand
Domain
- User
- Account
Infrastructure
- UserPO
- AccountPO
转换
- UserAssembler / UserMapper
👉 如果你项目中,这几类对象自然出现,说明你的架构已经开始成型。
七、为什么“多模型”不是浪费,而是护城河?
因为后端系统真正面对的是:
- 业务变化
- 接口变化
- 数据库变化
- 架构演进
对象分层的本质是:
👉 把变化关进笼子里。
- 页面变 → 主要影响 DTO / VO
- 流程变 → 主要影响 Command / Service
- 业务变 → 主要影响 Domain
- 存储变 → 主要影响 PO / Repository
👉 变化不扩散,系统才有长期生命力。
八、总结一句话
👉 各层一定都会有自己的数据 Bean。
👉 真正的后端架构能力,不在“类少”,而在:
每个对象,只说它那一层的话。
当你开始自然地区分:
- 协议模型
- 用例模型
- 领域模型
- 持久化模型
你就已经从“写接口的人”,迈进了“做系统的人”。
更多推荐


所有评论(0)