可以通过其所有属性确定实体



问题是 - 实体可以由所有属性定义,或者仅由它的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
}

在这里,我有全球唯一的钱包 - 那是骨料根。它有账单,我认为在这种情况下是实体(因为我可以更改账单状态,而且钱包里仍然是该法案)。可以通过在账单的任何一侧绘制一些字符串来改变状态(在这种情况下,这也是实体)。

Bill本身只有作为钱包的一部分的意义,而且在钱包中,我只能有1种账单(我不能有2个账单,只有10美元,例如一个)。

如果我将其视为价值对象,并且使其成为不可变的对象,那么每次我在账单上绘制某些内容时,我都必须制作新的账单 - 在这种情况下,这有点奇怪,并且在代码中也很难做。<<<<<<<<<<<<

如果我将其视为全球唯一的实体,则必须拥有实际上是[Wallet.id&amp;Bill.Billtype]。但是在这种情况下

最自然的事情是,我将法案视为实体,并且具有测试所有账单属性的平等方法(与此同时,侧面的所有属性都包含在账单类中)。

这种常见的情况是否具有?

尽管不是常见的做法,但值botem(vo)肯定可能是突变的(例如,出于绩效原因)。但是,您需要确保无法共享可变的VO

仍然,对可变的vo的需求也许是一个有力的指标,即您要建模的概念实际上是一个实体。一个好问题要问自己是您是否对此实例的生命周期感兴趣。

例如,在您的情况下,保持账单上的变更历史的历史重要吗?如果是,则应将账单建模为实体。

如果我将其视为全球独特的实体,我将不得不 具有账单的ID,实际上是[Wallet.id&amp; Bill.Billtype]。但是在这种情况下

不要忘记,从域模型的角度来看,实体必须仅在其骨料根(AR)中唯一地识别。这意味着billType可以用作钱包内的帐单ID。

还要注意,该账单可以从数据库的角度具有替代身份,或者(如果需要)(Walletid,cilltype)复合ID。注意:

  1. 重要的是要做出一个很好的决定,哪些对象是实体,哪个是vo。vo标识是由其内容(其代表的值)确定的。
    从您所描述的情况下还不清楚。
    通常,10 $是10 $,而Money是所有书籍在谈论vo。
    时显示的第一个示例但是,A Bill 可能是不同的,并且可能被视为实体。我可以有10美元的钞票,您可以拥有一张。它们的价值是相同的(在这个术语中是平等的),但是它们仍然是两个不同的实体,因此应该具有某些身份字段。但是,这可能不是您的情况。
    如果您 do 认为账单是相同的,如果它们具有相同的 billTypedrawing,则是vo。

  2. 在解散的第二部分中,通常是不变的,从性质和定义上都是不变的。如果您有复杂的VO,则可以考虑使用著名的构建器图案。

一般想法是使用下一个规则:

1)DDD与概念/概念之间的业务和关系有关。实施并非严格定义。因此,最好编写详细的故事,然后展示您如何在域图上看到它。

2)一个实体是:

许多物体不是从根本上由其属性定义的,而是 而是通过连续性和身份的线程。(埃文斯)

例如,订单可以具有订单网络,价格,船舶和其他属性。如果有人更改ShiptingAddress,则订单保持相同的对象,而不是新订单。

,即使您在系统中有两个订单,所有(订单网络,价格,船舶编号)仍然是不同的实体。唯一的区别是身份:ordernumber。

3)值对象由其所有属性定义。因此,这样做是不可变的,这很常见。

显而易见的例子是价格:

Price{
  readonly Currency Currency;
  readonly Decimal Amount;
}
value1 = new Price(Currency.USD, 1);
value2 = new Price(Currency.USD, 1);
Assert.IsTrue(value1 == value2);

不太明显的示例是总体中的vo的用法,这似乎适用于您的示例。

订单有订购,其中

OrderItem{
  string ProductSKU;
  int Amount;
}

OrderItem作为实体并添加OrderItemId属性,例如,用于数据库编辑可能很方便。从业务角度来看,大多数时候根本不知道OrderItemId。订购项目生活在其聚合根Order内,并严格地将外部识别为一对{Order, OrderItem}。在这种情况下,您甚至无法触摸OrderItem,而不必首先进入其汇总根。

现在,如果我们查看OrderItem,它是由其属性绝对识别的,那么它是值对象。


那么,"可以通过其所有属性来识别实体吗?" - 不,它是值对象的概念。

相关内容

  • 没有找到相关文章

最新更新