Skip to content

Day 07 - 值对象(Value Object)

📖 今日目标

  1. 理解值对象(Value Object)的概念
  2. 掌握值对象的设计原则
  3. 学会在实际场景中使用值对象

核心概念

什么是值对象?

值对象(Value Object) 是没有唯一标识,完全由其属性值定义的对象。它用于描述那些"是什么"而非"是谁"的概念。

值对象的核心特征:

  • 无标识:不关心"哪个",只关心"什么样"
  • 不可变:创建后属性不能改变
  • 可替换:相等属性的值对象可以互换

关键要点

1. 值对象的判断标准

问自己:这个对象是否需要唯一标识?

  • 需要标识 → 实体
  • 不需要标识 → 值对象

2. 常见值对象示例

实体值对象
OrderMoney, Address
UserEmail, PhoneNumber
ProductPrice, Dimension

3. 值对象的实现原则

java
public class Money {
    private final BigDecimal amount;
    private final Currency currency;
    
    public Money(BigDecimal amount, Currency currency) {
        this.amount = amount;
        this.currency = currency;
    }
    
    // 不可变:不提供setter
    // 相等性:通过属性判断
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Money money = (Money) o;
        return amount.equals(money.amount) && currency.equals(money.currency);
    }
}

4. 值对象的优势

  • 表达业务概念更清晰
  • 避免基本类型偏执
  • 便于验证和约束
  • 提升代码可读性

面试考点

问题:什么时候应该使用值对象?

答案:

使用值对象的场景:

  1. 描述性概念

    • 金额、地址、日期范围
    • 不需要区分"哪个"
  2. 可组合性

    • 将多个相关属性组合成单一概念
    • 如:Money = amount + currency
  3. 不可变性

    • 创建后不会改变
    • 任何修改返回新实例
  4. 相等性基于属性

    • 两个地址的所有属性相同则相等
    • 不需要追踪"哪个"地址

反面案例

  • ❌ 用String存储金额(精度丢失、货币不明)
  • ❌ 用String存储地址(无法验证格式)

正面案例

  • Money.of(100, Currency.CNY)
  • Address.of("北京", "朝阳区", "建国路88号")

实践思考

🎯 思考题

以下哪些适合作为值对象?

  1. 颜色(Color)
  2. 邮政编码(PostalCode)
  3. 用户(User)
  4. 电话号码(PhoneNumber)
  5. 车辆(Vehicle)

说明理由。


📚 扩展阅读


📅 学习进度

Day主题状态
01-06战略设计 + 实体
07值对象(Value Object)
08聚合(Aggregate)与聚合根
.........
30复习与总结

本文为DDD 30天学习计划第7天内容

📚 导航

| ← Day 06 - 上一章 | Day 08 - 下一章 →

最后更新: