Appearance
Day 07 - 值对象(Value Object)
📖 今日目标
- 理解值对象(Value Object)的概念
- 掌握值对象的设计原则
- 学会在实际场景中使用值对象
核心概念
什么是值对象?
值对象(Value Object) 是没有唯一标识,完全由其属性值定义的对象。它用于描述那些"是什么"而非"是谁"的概念。
值对象的核心特征:
- 无标识:不关心"哪个",只关心"什么样"
- 不可变:创建后属性不能改变
- 可替换:相等属性的值对象可以互换
关键要点
1. 值对象的判断标准
问自己:这个对象是否需要唯一标识?
- 需要标识 → 实体
- 不需要标识 → 值对象
2. 常见值对象示例
| 实体 | 值对象 |
|---|---|
| Order | Money, Address |
| User | Email, PhoneNumber |
| Product | Price, 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. 值对象的优势
- 表达业务概念更清晰
- 避免基本类型偏执
- 便于验证和约束
- 提升代码可读性
面试考点
问题:什么时候应该使用值对象?
答案:
使用值对象的场景:
描述性概念:
- 金额、地址、日期范围
- 不需要区分"哪个"
可组合性:
- 将多个相关属性组合成单一概念
- 如:Money = amount + currency
不可变性:
- 创建后不会改变
- 任何修改返回新实例
相等性基于属性:
- 两个地址的所有属性相同则相等
- 不需要追踪"哪个"地址
反面案例:
- ❌ 用String存储金额(精度丢失、货币不明)
- ❌ 用String存储地址(无法验证格式)
正面案例:
- ✅
Money.of(100, Currency.CNY) - ✅
Address.of("北京", "朝阳区", "建国路88号")
实践思考
🎯 思考题:
以下哪些适合作为值对象?
- 颜色(Color)
- 邮政编码(PostalCode)
- 用户(User)
- 电话号码(PhoneNumber)
- 车辆(Vehicle)
说明理由。
📚 扩展阅读
- 《领域驱动设计》第5章
- Value Object - Martin Fowler
📅 学习进度
| Day | 主题 | 状态 |
|---|---|---|
| 01-06 | 战略设计 + 实体 | ✅ |
| 07 | 值对象(Value Object) | ✅ |
| 08 | 聚合(Aggregate)与聚合根 | ⬜ |
| ... | ... | ... |
| 30 | 复习与总结 | ⬜ |
