天天看點

位元組面試:說說聚合與聚合根怎麼設計

作者:人人都是産品經理
本文作者分析了位元組面試題,圍繞領域驅動設計,解釋了基本概念聚合與聚合根,介紹了一些設計原則和如何設計使用。
位元組面試:說說聚合與聚合根怎麼設計

一、聚合

在領域驅動設計(DDD)中,聚合是一個核心概念,它幫助開發者管理複雜性,特别是在處理大量相關對象時。

聚合是由緊密關聯的實體和值對象組成,是修改和儲存資料的基本機關。每個聚合都有一個倉庫,用于儲存聚合的資料。

聚合有一個聚合根和上下文邊界,邊界根據業務需求和内聚原則,定義了聚合應該包含哪些實體和值對象,而聚合之間是松耦合的,這樣設計的微服務,會很自然地實作高内聚、低耦合。

聚合在 DDD 分層架構中是領域層的一部分,領域層可以包含多個聚合,共同實作核心業務邏輯。實體在聚合内以充血模型實作業務能力,保證業務邏輯的高内聚。

跨多個實體的業務邏輯通過領域服務來實作,跨多個聚合的業務邏輯通過應用服務來實作。

二、聚合根

在傳統資料模型中,每個實體都是獨立的。如果随意修改和調用實體,可能會導緻資料邏輯不一緻。使用鎖的方式會使軟體變得複雜,降低系統性能。

可以把聚合根看作是部門的負責人,它不僅是實體,也是這個聚合“部門”的管理者。

聚合根作為實體時,有自己的屬性和業務行為,執行自己的業務邏輯。

當聚合根作為管理者,它在聚合内部協調實體和值對象,按照固定的業務規則完成業務邏輯。

當聚合之間協作時,聚合根是對外的接口人。它通過自己的ID關聯其他聚合,接受外部請求。如果需要通路聚合内的其他實體,必須先通路聚合根,然後導航到聚合的内部實體。外部對象不能直接通路聚合内實體。

三、聚合的一些設計原則

設計聚合時,遵循一些核心原則可以確定聚合的有效性、一緻性。

1. 選擇合适的聚合根

每個聚合都應有一個聚合根,它是聚合中最重要的實體,其他實體和值對象通過聚合根關聯。聚合根應該是能夠代表整個聚合的實體,它負責保證聚合内部資料的一緻性和完整性。選擇聚合根時,應考慮哪個實體在業務中扮演核心角色,并且能有效地管理和封裝聚合的行為。

2. 聚合最小化

聚合應盡可能地小,隻包含必須由聚合根直接管理的實體和值對象。這樣可以降低聚合内部的複雜性,提高聚合的内聚性,小的聚合更容易了解和維護。

3. 封裝業務規則

聚合根應該封裝其聚合内部的業務規則,任何對聚合内部資料的修改,都應通過聚合根的方法進行通路,方法執行後應保證所有業務規則都被正确執行。通過這種方式,聚合根可以確定聚合的狀态始終一緻。

4. 聚合間的引用通過辨別符

聚合之間不應直接引用對方的實體,而應該通過辨別符(如ID)進行引用。這樣做有助于減少聚合間的耦合,使得各個聚合可以獨立地進行變更和擴充,而不會影響到其他聚合。

5. 一緻性邊界的定義

設計聚合時,要明确哪些操作必須是強一緻的,即在完成操作後,聚合的狀态必須是一緻,這涉及到事務操作。聚合應該是最小的一緻性邊界,任何事務應當隻在單個聚合的範圍内完成,不應跨聚合操作。

四、如何設計和使用聚合和聚合根

我們以電商平台的訂單系統為例,看看聚合和聚合根是如何設計和使用的。

在訂單系統中,訂單通常作為聚合根,因為訂單是整個業務流程中最核心的業務對象。

訂單聚合包括多個實體對象,如訂單明細、支付資訊、收貨資訊等。

訂單明細:聚合内的實體,每個訂單明細代表訂單中的一個購買項。它包括商品ID、購買數量、單價和小計。訂單明細與訂單緊密關聯,其生命周期由訂單聚合根管理。

支付資訊:也是聚合内的實體,支付資訊記錄了支付方式(如信用卡、支付寶、微信支付)、支付狀态、支付金額和支付時間等,這些資訊對于完成交易和進行财務核算至關重要。

收貨資訊:通常是一個值對象,包含省、城市、街道和郵編等資訊。因為它沒有獨立的辨別,僅僅描述了一個地理位置。

通過設計正确的聚合,訂單系統的業務操作會非常清晰,并能夠集中管理。

下面列舉一些常見的業務操作,介紹聚合是如何被使用的。

1. 訂單建立操作

當客戶選完商品,并送出訂單時,系統會觸發訂單建立的流程。

系統首先建立一個新的訂單聚合執行個體,此執行個體以訂單為聚合根。訂單聚合根包含了必要的資訊,如訂單編号、訂單初始狀态等。

客戶標明的每個商品都會作為訂單明細,添加到訂單中。每個訂單明細實體包括商品ID、購買數量和單價等資訊。這些訂單明細在建立過程中由訂單聚合根動态管理,確定資料的完整性。

客戶提供的收貨位址被建立為值對象,并與訂單聚合關聯。同時,初始化的支付資訊也會被設定為一個實體,包括支付方式和支付狀态等資訊。

2. 支付處理

當客戶進行支付時,支付資訊實體會被更新,包括記錄支付金額、支付方式、支付時間等。訂單聚合根確定支付資訊與訂單的狀态保持一緻性。

支付成功後,訂單聚合根會将訂單狀态更新為“已支付”,這是通過聚合内部的業務邏輯完成,確定所有資料一緻。

3 .發貨處理

在訂單準備發貨時,訂單聚合根會驗證存儲的收貨位址資訊的完整性和準确性。如果位址不完整,可能會要求客戶提供更多資訊,或進行二次确認。

一旦發貨位址驗證無誤,且商品準備就緒,訂單聚合根将訂單狀态更新為“已發貨”。随後,實際物流操作開始進行,并在系統中記錄和跟蹤發貨的過程資訊。

本文由 @湯師爺 原創釋出于人人都是産品經理。未經許可,禁止轉載。

題圖來自Unsplash,基于CC0協定。

該文觀點僅代表作者本人,人人都是産品經理平台僅提供資訊存儲空間服務。

繼續閱讀