领域模型中实体与行为高度内聚,本质是让对象知道自己该做什么:email字段绑定格式校验、status字段决定状态转换权限、password字段强制加密存储,所有逻辑封装在user或order类内部,而非散落在工具类或服务层。

领域模型中的实体与行为高度内聚,本质是让“对象知道自己该做什么”——不是把业务规则扔给工具类或服务层兜底,而是让数据和它天然该遵守的约束、该响应的状态变化,牢牢绑定在同一个类里。
实体即行为载体,不是数据容器
一个 User 实体不该只是字段集合。它的 email 字段天然关联邮箱格式校验;status 字段天然决定能否执行 activate() 或 deactivate();password 字段天然要求加密后存储。这些逻辑写在 User 类内部,而不是散落在 UserService、UserValidator、PasswordEncryptor 里。
- ✅ 正确:user.setEmail("a@b.com") 在 setter 中自动校验格式,不合法直接抛异常
- ✅ 正确:user.confirmOrder() 内部检查当前状态是否为 DRAFT,否则拒绝操作
- ❌ 错误:new UserHelper().isValidEmail(user.getEmail()) —— 校验脱离主体,无法随字段语义演进
行为封装体现状态生命周期
高内聚的实体清楚自己有哪些合法状态、哪些状态转换路径、哪些操作必须前置条件。比如 Order 实体应定义 transitionTo(OrderStatus target),并在方法内控制:DRAFT → CONFIRMED 允许,CONFIRMED → SHIPPED 允许,但 DRAFT → SHIPPED 直接拒绝。
- 状态变更逻辑由实体自身裁决,外部无需重复 if (order.getStatus() == DRAFT) 判断
- 所有创建、修改入口(构造器、setter、行为方法)都强制走同一套校验,避免绕过规则的“后门”
- 测试时只需 new Order().setItems(...).confirm(),就能完整覆盖业务规则,不依赖数据库或服务层
类型选择强化语义内聚
用对类型,是从语言层面防止行为与数据脱节。Boolean 代替 boolean 防止 NULL 被误转为 false;BigDecimal 代替 double 避免金额计算漂移;Instant 代替 Date 明确表达“无时区时间点”;枚举代替 String 确保 status 只能是预设值。
- 这些类型本身不带业务逻辑,但它们让 setter 和行为方法能精准响应真实业务约束
- 例如 setAmount(BigDecimal amount) 可以天然 throw IllegalArgumentException if amount.compareTo(BigDecimal.ZERO)
- 而用 double amount 就只能靠文档提醒“不能为负”,编译器和 IDE 都拦不住错误传入
DTO 与领域实体严格分界
DTO 只负责跨层搬运数据,不做任何判断、转换或校验。它没有行为,也不该有 isValidEmail() 这样的方法。所有业务含义、状态约束、合法性检查,只存在于 Domain Entity 或专门的领域服务(如 OrderPolicy)中。
- Controller 接收 UserDto → 构造 User 实体 → 调用 user.validateAndCreate()
- UserDto 不参与任何业务决策,它只是“临时信封”,拆开后规则立刻由 User 承担
- 这样既保证了领域逻辑集中可测,又让传输对象轻量、无副作用、易于序列化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











