【发布时间】:2017-02-20 11:37:24
【问题描述】:
问题是 - 实体可以由它的所有属性或仅由它的 Id 定义。
这是一个例子:
class Wallet{
int id;
Map<BillType, Bill> bills; //can have only 1 bill per bill type
void addBill(BillType billType, Bill bill){
this.bills.put(billType, bill);
}
}
//this is probably an Entity, since it is mutable, but it has no global Id (only local bound to wallet)
//and equality is based on all of the properties
class Bill{
BillType billType;
Map<TypeOfBillSide, SideOfBill> billSides; //can have only front or back
Bill(BillType billType){
this.billType = billType;
}
void drawWithPenOnBillSide(TypeOfBillSide typeOfBillSide, String drawing){
this.billSides.get(typeOfBillSide).drawWithPenOnBillSide(drawing);
}
void burn(){
System.out.println("I burned this bill");
}
}
//this is probably an Entity, since it is mutable, but it has no global Id (only local bound to Bill)
//and equality is based on all of the properties
class SideOfBill{
TypeOfBillSide typeOfBillSide;
String drawing;
public SideOfBill(TypeOfBillSide typeOfBillSide) {
this.typeOfBillSide = typeOfBillSide;
}
void drawWithPenOnBillSide(String drawing){
this.drawing = drawing;
System.out.println("I draw on this side " + this.drawing);
}
}
enum BillType{
DOLLAR_10,
DOLLAR_20,
DOLLAR_50;
}
enum TypeOfBillSide{
FRONT_SIDE,
BACK_SIDE
}
这里我有一个全球唯一的钱包——即聚合根。它有账单,我认为在这种情况下是实体(因为我可以更改账单的状态,但钱包中的账单仍然是该账单)。状态可以通过在票据的任何一侧绘制一些字符串来改变(SideOfBill - 在这种情况下也是一个实体)。
票据本身仅作为钱包的一部分才有意义,而且在钱包中我只能有一种票据(我不能有 2 张 10 美元的钞票,例如只有一张)。
如果我将其视为 Value 对象,并使其不可变,那么每次我在 Bill 上绘制一些东西时,我都必须制作新的 bill——在这种情况下,这有点奇怪,而且在代码中也很难做到。
如果我将其视为全球唯一的实体,我将必须拥有 Bill 的 ID,它实际上是由 [Wallet.Id & Bill.billType] 合成的。但在这种情况下,Wallet.id 并不自然适合 Bill 类。
最自然的事情是,我将 Bill 视为 Entity 并具有用于测试所有 Bill 属性的 equals 方法(同时测试 SideOfBill 的所有属性,因为它包含在 Bill 类中)。
这种情况常见吗?
【问题讨论】:
-
如果它是一个实体,那么为什么不添加一个 ID 呢?
-
@OfirWinegarten 因为我不需要 ID。就是这样 - 我不确定是否应该将其建模为实体或值对象。我需要有更改状态的选项(在票据上绘制),但同时两张不在钱包中且具有相同绘制的票据可以被视为相等。
-
那么我认为它应该是一个值对象,因为您不关心实例,而是关心内容。
-
还有
SideOfBill -
@OfirWinegarten 可以这样。这种方法的问题是,如果我需要在侧面画一些东西——我必须每次都创建新的 SideOfTheBill,然后用这个新的更新的 SideOfTheBill 创建新的 Bill(因为值对象应该是不可变的)——看起来像很多代码?
标签: java entity domain-driven-design identity value-objects