1. PO(Persistence Object,持久化对象)
-
定义:与数据库表结构直接映射的对象,通常用于ORM(如Hibernate、MyBatis)操作数据库。
-
职责:表示数据库中的一条记录。
-
特点:
-
属性与数据库表字段一一对应。
-
通常不包含业务逻辑。
-
-
示例:
@Entity @Table(name = "user") public class UserPO { @Id private Long id; private String username; private String email; // getters/setters }
2. DO(Domain Object,领域对象)
-
定义:在领域驱动设计(DDD)中表示核心业务逻辑的实体对象,与PO类似但关注点不同。
-
职责:封装领域模型的属性和行为(业务逻辑)。
-
特点:
-
可能包含业务方法(如校验规则、状态转换)。
-
在阿里Java规范中,DO(Data Object)可能直接对应PO。
-
-
示例:
public class UserDO { private Long id; private String username; // 业务方法,例如校验用户名 public boolean isValidUsername() { return username != null && username.length() >= 6; } }
3. BO(Business Object,业务对象)
-
定义:封装复杂业务逻辑的对象,可能组合多个PO/DO。
-
职责:处理跨实体的业务逻辑,例如订单创建涉及用户、商品、库存等。
-
特点:
-
可能包含多个PO/DO的聚合。
-
实现核心业务规则。
-
-
示例:
public class OrderBO { private OrderPO orderPO; private UserPO userPO; private List<ProductPO> products; // 计算订单总价 public BigDecimal calculateTotalPrice() { ... } }
4. DTO(Data Transfer Object,数据传输对象)
-
定义:用于不同层(如Controller-Service)或服务间(如微服务)传输数据的对象。
-
职责:减少网络传输次数,避免暴露内部数据结构。
-
特点:
-
扁平化结构,可能组合多个领域对象的数据。
-
无业务逻辑,仅包含数据字段。
-
-
示例:
public class UserDTO { private Long id; private String username; private String avatarUrl; // 可能由多个PO组合而来 // getters/setters }
5. VO(Value Object,值对象 / View Object,视图对象)
-
定义:用于展示层(如前端页面),封装界面需要的数据。
-
职责:适配前端需求,格式化数据(如日期、金额)。
-
特点:
-
字段可能与数据库表不完全对应。
-
包含展示逻辑(如状态码转文本)。
-
-
示例:
public class UserVO { private String username; private String formattedRegisterDate; // "2023-10-01" // getters/setters }
关键区别总结
对象 层级 核心职责 典型场景 PO 数据访问层(DAO) 数据库映射 MyBatis/Hibernate操作数据库 DO 领域层(Domain) 封装领域模型和业务规则 DDD中的实体对象 BO 业务逻辑层(Service) 复杂业务逻辑聚合 跨多个PO/DO的业务操作 DTO 传输层 跨层/跨服务数据传输 Controller-Service交互 VO 展示层(View) 适配前端展示需求 返回给前端的JSON数据
注意事项
-
实际项目中的简化:
-
小型项目可能合并某些对象(如PO直接作为DTO使用),但中大型项目建议分层。
-
-
命名差异:
-
不同公司/框架可能有不同习惯(如阿里规范中DO替代PO)。
-
-
工具支持:
-
使用MapStruct、ModelMapper等工具简化对象间转换。
-
通过合理使用这些对象模型,可以显著提高代码的可维护性和扩展性。