簡體   English   中英

DDD實體構造函數參數

[英]DDD entity constructor parameters

如果您有一個帶有值對象作為屬性的實體。

實體構造函數(值對象)的參數是哪個? 還是價值對象的原始類型?

首先,我完成了在實體外部構建值對象的工作,然后將值對象傳遞給了實體構造函數……但是后來我意識到也許是實體本身必須構建值對象。

我之所以這樣想,是因為實體和值對象實際上是一個聚合,並且假定您必須通過聚合根(即通過實體)訪問聚合的內部。

那么哪種方法正確呢? 是否允許在實體外部處理值對象? 還是實體可以使用值對象?

謝謝。

編輯:

例如,我有一個實體“任務”,它是聚合根。 該實體具有值對象“ DeliveryDate”(格式為“ dd / mm / yyyy hh:mm”)。 實體也有更多的價值對象。

class DeliveryDate extends ValueObject {

    private String formattedDeliveryDate;

    private DeliveryDate() {
        super();
    }

    DeliveryDate ( String formattedDeliveryDate ) {
        this();
        this.setFormattedDeliveryDate ( formattedDeliveryDate );
    }

    private void setFormattedDeliveryDate ( String formattedDeliveryDate ) {
        << check that the string parameter "formattedDeliveryDate" is a valid date in format "dd/mm/yyyy hh:mm" >>
        this.formattedDeliveryDate = formattedDeliveryDate;
    }

    ........     

實體構造函數:

Task ( TaskId taskId, Title title, Delivery deliveryDate, EmployeesList employeesList ) {
    this();
    this.setTaskId(taskId);
    this.setTitle(title);
    this.setDeliveryDate(deliveryDate);
    this.setEmployeesList(employeesList);
}

我的疑問是:這樣可以嗎? (傳遞給構造函數DeliveryDate對象)還是應該傳遞字符串? (然后構造函數創建DeliveryDate對象)

我認為這是一個更多的問題,“總體之外的人應該知道DeliveryDate概念嗎?”

總的來說,我對任何實體的任何價值對象都存有疑問,而不僅僅是Task和DeliveryDate(這只是一個例子)。

我已經問過有關構造函數的問題,但是它對工廠也是有效的(如果創建實例的過程很復雜)...聚合工廠參數應該是值對象嗎? 或創建值對象的原語?

域驅動設計這里沒有提供任何具體指導。

一個常見的情況可能是這樣的:我們已經從數據庫中檢索了一個DTO,現在想從中創建一個實體。

class Entity {
    private Value v;

    Entity (Value v) {
        if (null == v) throw new IllegalArgumentException();

        this.v = f;
    }

    Entity (DTO dto) {
        this(new Value(dto));
    }

    // ...
}

調用第二個構造函數而不是第一個構造函數真的重要嗎? 不多。

語言檢查:

不從數據庫檢索DTO。 您從數據庫檢索到的是匯總而不是DTO

我不得不放棄這個想法-這個定義導致太多問題。

例如,在基於事件的設計中,數據庫通常存儲事件的表示形式,而不是集合。

即使在傳統設計中,它也不會成立-聚合的邊界由領域模型強制執行的約束定義。 一旦將數據從域模型中取出,剩下的只是狀態的表示。 換句話說,我們將狀態保存在數據庫中,但不保存行為,也不保存約束-您不能從保存的數據中獲取約束,因為您看不到邊界。

是由模型而不是數據庫來決定哪些數據需要在內部保持一致。

我傾向於使用術語DTO,因為它的作用是: 在流程之間 (在這種情況下,在數據庫和域模型之間) 攜帶數據 如果您想使用消息或文檔,我不會打擾。

在您的情況下,這兩種解決方案似乎很相似。 在實體的外部還是內部創建值對象並不重要。 但是請考慮一下,當您的實體將具有多個值對象時,實體構造函數將包含太多邏輯,以確保其正確創建VO並同時強制執行實體的不變式。

避免這種不必要的復雜性的一種解決方案是使用工廠。 工廠將抽象化創建過程,這將使您的實體代碼變得簡單。

在DDD中,工廠對於創建聚合非常有用。 藍皮書中有一整章是關於工廠的,這是關於在DDD中使用工廠的好文章http://culttt.com/2014/12/24/factories-domain-driven-design/

編輯

我的疑問是:這樣可以嗎? (傳遞給構造函數DeliveryDate對象)還是應該傳遞字符串? (然后構造函數創建DeliveryDate對象)

是的,沒關系。 任務不應該知道如何創建值對象。 您不應傳遞會導致給Task構造函數增加更多復雜性和責任的字符串。

我認為這是一個更多的問題,“總體之外的人應該知道DeliveryDate概念嗎?”

是的,聚合的外部知道DeliveryDate並不是問題。 這與了解字符串和整數相同。 值對象易於處理和推理,它們是領域的一部分,因此我認為在集合之外處理它們沒有問題。

匯總工廠參數應該是值對象嗎? 或創建值對象的原語?

在這里,我要說的是Factory應該接收原始類型並封裝對象創建。 因為如果將values對象傳遞給工廠,它將只是將相同的參數傳遞給Entity構造器,這就是中間人的味道

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM