跳转到内容

PO/DO/DTO/VO 模型规约

用途:一个字段该加在哪个类上、对象能不能跨层传递时查阅

缩写 全称/含义 归属层 生命周期 允许包含行为
PO / DO 持久化对象,与表结构对应 基础设施层 存取期间 无(纯字段)
Entity / 领域对象 业务模型,含不变式 领域层 用例执行期间 有(状态迁移、校验)
BO 业务对象(部分团队指服务内部聚合结构) 应用/领域层 视团队约定 视情况
DTO 数据传输对象,跨进程/跨模块契约 接口层、client 包 一次调用 无(可有基础校验)
VO 视图对象,面向页面展示结构 接口层/查询服务 一次渲染 无(可有格式化)
Query/Command 请求参数对象 接口层入口 一次请求 无
  1. 持久化对象不出基础设施层:PO/DO 不出现在应用服务签名与接口层,否则表结构变更会扩散到前端。
  2. 领域对象不跨进程传输:领域模型含行为与不变式,序列化外传会丢语义;对外一律 DTO。
  3. 转换只发生在边界:入口(Query/Command → 领域)、出口(领域 → DTO/VO)、存取(领域 ↔ PO)三处,避免链式映射。
  4. VO 由查询侧生成:展示结构允许直接读投影表/宽表,不必经过聚合。
  5. 契约独立版本化: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 相关)