1. 程式人生 > 程式設計 >領域驅動設計DDD之資源庫

領域驅動設計DDD之資源庫

為什麼使用資源庫?

如果完全按照領域模型的角度,完全通過遍歷物件的方法來獲取所有關聯的物件。這種模型會過於錯綜複雜。物件巢狀的層級或者關聯的層級非常深。例如通過Customer.order.product.price層層遍歷來獲取當時客戶訂單的商品的價格。

那如果完全按照資料庫模型的角度,模型中的物件不需要完全連線起來,物件關係網就能保持在一個可控範圍。但是這又會回到之前傳統開發模式中,零散的使用各個DAO從各個表抽取資料自行拼湊出我們想要的模型。

這裡就會出現一個問題,Customer類需要保持客戶所有已訂的Order,還是通過CustomerID在資料庫中查詢Order列表呢?

物件關聯還是純資料庫?

客戶需要一種有效的方式來獲取已存在的領域物件的引用。如果基礎設施提供了這方面的遍歷,那麼開發人員可能會增加很多可遍歷的關聯,這會使模型變得非常混亂。另一方面,開發人員可能使用查詢從資料庫中提取他們所需的資料,或是直接提取具體的物件,而不是通過聚合的根來得到這些物件。這樣就導致領域邏輯進入查詢和客戶程式碼中,而實體和值物件變成了單純的資料容器。採用大多數處理資料庫訪問的技術複雜性很快就會使客戶程式碼變得混亂,這將導致開發人員簡化領域層,最終使模型變得無關緊要。

我們需要找到一個恰當的方式。

我們不需要對那麼很容易通過遍歷來找到的持久物件進行查詢訪問,如不需要單獨的去獲取地址,而可以通過Person物件來獲取地址,意味著當我們獲取Person物件的時候,地址值物件已經是填充好的。我們不需要特地利用另外一個資源庫的方法,獲取地址再進行填充。但當獲取Person的所有訂單記錄時,由於訂單的數量有時候過於龐大,載入Person的時候其實並不一定需要檢視訂單記錄,我們應該使用Repository的另外方法來獲取Person的訂單記錄。

對值物件的全域性搜尋通常是沒有意義的。如果確實需要在資料庫中搜索一個已知的值物件,那麼值得考慮一下,搜尋結果可能實際上是一個實體,尚未識別出它的標識。

定義

在所有持久化物件中,有一小部分必須通過基於物件屬性的搜尋來全域性訪問。當很難通過遍歷的方式來訪問某些聚合根的時候,就需要這種訪問方式,它們通常是實體,有時可能是具有複雜內部結構的值物件。而其他物件則不適合使用這種訪問方式,因為這會混淆它們之間的重要區別。隨意的資料庫查詢會破壞領域物件的封裝和聚合。技術基礎設施的資料訪問機制的暴露會增加客戶的複雜度,並妨礙模型驅動的設計。

如何使用資源庫

我們應該將資源庫看作一個物件的集合。

客戶使用查詢方法向資源庫請求物件,這些查詢方法根據客戶所指定的條件來挑選物件。資源庫檢索被請求的物件,並封裝資料庫查詢和元資料對映機制。他們可以返回彙總的資訊,如多少個例項滿足條件。甚至返回彙總計算,如所有匹配物件的某個數值屬性的總和。

這樣一來客戶就只需與一個簡單的、易於理解的介面進行對話,並根據模型向這個介面提出它的請求。

為每種需要全域性訪問的物件型別建立一個資源庫,這個資源庫相當於該型別的所有物件在記憶體的一個集合的“替身”。通過一個眾所周知的全域性介面來提供訪問。提供新增和刪除物件的方法,用這些方法來封裝在資料儲存中實際插入和刪除資料的操作。根據提供具體條件來挑選物件的方法,並返回屬性值滿足條件的物件或者物件集合,從而將實際的儲存和查詢技術封裝起來。只為那些確實需要直接訪問的聚合根提供資源庫,讓客戶始終聚焦於模型,而將所有物件的儲存和訪問操作交給資源庫來完成。

讓使用者無感知的,以為就在記憶體中使用一個集合一樣。

資源庫的方法設計:

方法引數:

  1. 唯一標識
  2. 複雜的引陣列合
  3. 值域(日期範圍)

返回值:

  1. 物件
  2. 物件集合
  3. 某些型別的彙總。

資源庫的實現

  1. 對型別進行抽象,比如有賓士車寶馬車,不應有兩種資源庫,而應該是隻有一個抽象車類的資源庫。
  2. 充分利用與客戶進行解耦。
  3. 將事務的控制權交給客戶。

資源庫的優點

  1. 為客戶提供了一個簡單的模型,可用來獲取持久化物件並管理他們的生命週期。
  2. 他們將應用程式和領域設計與持久化技術進行解耦。
  3. 它們體現了有關物件訪問的設計決策。
  4. 很容易測試,將利用集合直接替換資源庫進行測試。

資源庫中如何管理事務

對事務的管理絕對不應該放在領域模型和領域層中。通常來說,與領域模型相關的操作都非常的細粒度,以致於無法用於管理事務。另外,領域模型也不應該意識到事務的存在。通常我們將事務放在應用層,然後為每個主要的用例建立一個門面,一個用例對應一個門面業務方法,如果所有操作安全完成的話,門面中的業務方法提交事務,否則失敗回滾。

關於DDD的理解各有不同,歡迎網友評論一起探討。

轉自我的個人部落格 vc2x.com