Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DDD TW 7th 導讀 - Ch11 Factory

DDD TW 7th 導讀 - Ch11 Factory

Avatar for James Wang

James Wang

July 03, 2019
Tweet

More Decks by James Wang

Other Decks in Programming

Transcript

  1. Factory in DDD 當建立一個物件或建立整個 Aggregate 時,如果建立的工作很複雜,或者暴露過多的 內部結構,則可以使用 Factory 進行封裝。 使用動機:

    • 將建立複雜物件的實例和 Aggregate 的職責轉移給單獨的物件。 • 封裝建立 Aggregate 時所有職責,譬如創建物件時的檢核。舉例來說,建立「狗」 的物件,傳入屬性「狗腿」個數,則需檢核「狗腿」不能大於 4 條腿。 • 透過工廠,建立 Aggregate 時要把它作為一個整體,並確保它滿足固定規則。
  2. Aggregate Root 中的 Factory • 最常見的運用之一。 • 主要職責是一口氣將該 Aggregate Root

    底下所有 Aggregate 建立起來。 • 也負責建立 Aggregate 所需邏輯與檢核。
  3. 一般的寫法 建構式中做完初始化所有功能。 public class Order : EntityBase, IAggregateRoot { public

    decimal Total { get; private set; } public Order(Guid id, IEnumerable<Product> orderItems) : base(id) { // 針對 Products 檢核(略) // 計算總金額 var total = 0m; foreach (var item in orderItems) { if (item.UnitPrice > 0) { total += item.UnitPrice; } else { throw new ArgumentOutOfRangeException(nameof(item.UnitPrice)); } } Total = total; } }
  4. 套用工廠寫法 透過工廠呼叫 Aggregate Root。 public class OrderFactory { public Order

    Create(Guid id, IEnumerable<Product> orderItems) { // 針對 Products 檢核(略) // 計算總金額(略) return new Order(id, orderItems); } }
  5. 套用工廠寫法 另外一種寫法。 public class Order : EntityBase, IAggregateRoot { public

    List<Product> OrderItems { get; } = new List<Product>(); private Order(Guid id) : base(id) { } public static Order NewOrder(Guid id) { return new Order(id); } public void Create(IEnumerable<Product> orderItems) { // 針對 Products 檢核(略) // 計算總金額(略) } }
  6. 各式各樣的工廠 • Domain Service Factory • Entity Factory • Value

    Object Factory 簡單說,當你發現建造物件很複雜時,都能套用工廠模式。 BUT… 有時候其實是你設計不好導致太複雜。 所以套用工廠模式前,請回頭看看自己的設計是否有沒有問題。
  7. Recap • 當覺得建立或重建物件很複雜或想要隱藏細節的地方,都能用工廠。 • 在 DDD 中,常用於 Aggregate Root,在建立 Aggregate

    時要把它視為一個整體 ,並確保它滿足固定規則,保證 Aggregate 狀態的正確性。 • 使用工廠之前,先確認所謂的複雜是不是設計不良引起的。有些情況下只需要使 用建構子。 • 工廠是放置固定規則相關邏輯的合適地方。 • 透過工廠封裝,表達限界上下文的通用語言。