- 无ID属性
- 判断相等的方法只能是抽象方法
值对象没有ID属性,也就没有对应字段,这意味着我们没办法在基类中判断两个值对象是否相等。为了判断其结构相等,我们可以在基类中构建基础方法:
package com.lugew.springbootddd;
/**
* @author 夏露桂
* @since 2021/6/8 17:40
*/
public abstract class ValueObject<T> {
@Override
public boolean equals(Object obj) {
T valueObject = (T) obj;
if (valueObject == null)
return false;
return equalsCore(valueObject);
}
@Override
public int hashCode() {
return getHashCodeCore();
}
protected abstract boolean equalsCore(T other);
protected abstract int getHashCodeCore();
}
可以看到我们重写了equals
和hashCode
方法,并且将具体的实现委托给了其子类。此时,我们可以将Money
类进行重构:
package com.lugew.springbootddd.snackmachine;
import com.lugew.springbootddd.ValueObject;
/**
* @author 夏露桂
* @since 2021/6/7 11:59
*/
public class Money extends ValueObject<Money> {
private final int oneCentCount;
private final int tenCentCount;
private final int quarterCount;
private final int oneDollarCount;
private final int fiveDollarCount;
private final int twentyDollarCount;
public Money(int oneCentCount, int tenCentCount, int quarterCount, int
oneDollarCount, int fiveDollarCount, int twentyDollarCount) {
this.oneCentCount = oneCentCount;
this.tenCentCount = tenCentCount;
this.quarterCount = quarterCount;
this.oneDollarCount = oneDollarCount;
this.fiveDollarCount = fiveDollarCount;
this.twentyDollarCount = twentyDollarCount;
}
public static Money add(Money money1, Money money2) {
return new Money(
money1.oneCentCount + money2.oneCentCount,
money1.tenCentCount + money2.tenCentCount,
money1.quarterCount + money2.quarterCount,
money1.oneDollarCount + money2.oneDollarCount,
money1.fiveDollarCount + money2.fiveDollarCount,
money1.twentyDollarCount + money2.twentyDollarCount);
}
@Override
protected boolean equalsCore(Money other) {
return oneCentCount == other.oneCentCount
&& tenCentCount == other.tenCentCount
&& quarterCount == other.quarterCount
&& oneDollarCount == other.oneDollarCount
&& fiveDollarCount == other.fiveDollarCount
&& twentyDollarCount == other.twentyDollarCount;
}
@Override
protected int getHashCodeCore() {
int hashCode = oneCentCount;
hashCode = (hashCode * 397) ^ tenCentCount;
hashCode = (hashCode * 397) ^ quarterCount;
hashCode = (hashCode * 397) ^ oneDollarCount;
hashCode = (hashCode * 397) ^ fiveDollarCount;
hashCode = (hashCode * 397) ^ twentyDollarCount;
return hashCode;
}
}
父类的抽象方法equalsCore
,getHashCodeCore
子类是必须实现的。equalsCore
根据每个字段的值来判断两个值对象是否相等。
在这里,我再次重申实体和值对象的区别:实体ID相等而值对象结构相等,值对象不存在ID字段。