用途:一个字段该加在哪个类上、对象能不能跨层传递时查阅
| 缩写 |
全称/含义 |
归属层 |
生命周期 |
允许包含行为 |
| PO / DO |
持久化对象,与表结构对应 |
基础设施层 |
存取期间 |
无(纯字段) |
| Entity / 领域对象 |
业务模型,含不变式 |
领域层 |
用例执行期间 |
有(状态迁移、校验) |
| BO |
业务对象(部分团队指服务内部聚合结构) |
应用/领域层 |
视团队约定 |
视情况 |
| DTO |
数据传输对象,跨进程/跨模块契约 |
接口层、client 包 |
一次调用 |
无(可有基础校验) |
| VO |
视图对象,面向页面展示结构 |
接口层/查询服务 |
一次渲染 |
无(可有格式化) |
| Query/Command |
请求参数对象 |
接口层入口 |
一次请求 |
无 |
- 持久化对象不出基础设施层:
PO/DO 不出现在应用服务签名与接口层,否则表结构变更会扩散到前端。
- 领域对象不跨进程传输:领域模型含行为与不变式,序列化外传会丢语义;对外一律 DTO。
- 转换只发生在边界:入口(Query/Command → 领域)、出口(领域 → DTO/VO)、存取(领域 ↔ PO)三处,避免链式映射。
- VO 由查询侧生成:展示结构允许直接读投影表/宽表,不必经过聚合。
- 契约独立版本化:
client 模块里的 DTO 是对外承诺,新增字段兼容、删除或改语义要升版本。
| 类型 |
命名 |
位置 |
| 持久化对象 |
XxxDO / XxxPO |
infrastructure/persistence/dataobject |
| 领域对象 |
Xxx(业务名) |
domain/<context>/model |
| 传输对象 |
XxxDTO / XxxRequest / XxxResponse |
client 或 adapter/web/payload |
| 视图对象 |
XxxVO |
adapter/web/vo 或查询服务 |
| 转换器 |
XxxAssembler / XxxConverter |
与被转换对象同层边界处 |
- 用映射生成器消除样板(MapStruct 类工具),但保留显式转换代码可读性:复杂语义转换手写。
- 简单模块允许减少模型数量(例如只有 DTO + 领域对象),不要机械照搬五套模型。
- 禁止用
BeanUtils.copyProperties 类反射拷贝承担跨层转换:字段改名不会报错,问题在运行时才出现。
| 误区 |
后果 |
修正 |
| 一个实体类贯穿所有层 |
表字段泄露到界面,改表要发前端 |
分层模型 + 边界转换 |
| DTO 里写业务规则 |
规则无守护点,换个入口即绕过 |
规则回领域对象 |
| VO 直接返回聚合 |
暴露内部结构与不变式细节 |
查询侧专用投影 |
| 链式多层映射(PO→BO→DTO→VO) |
无意义的样板与性能开销 |
只在必要边界转换 |
| 反射拷贝跨层 |
字段漂移无编译期反馈 |
显式转换或代码生成 |
- 阿里巴巴 Java 开发手册(AO/DO/DTO/VO 命名规约章节)
- Alibaba COLA 项目的分层模型示例
- Martin Fowler《企业应用架构模式》第 4 章(Domain Object / Service Layer 相关)