地精是正確的,很少有情景我可以想像這將要求你可能想擺脫它的AddressRepository。
這就是說,您要查找的設計概念是「Aggregate Root」。這很快就意味着要識別對象圖中沒有其他對象不存在的對象。這些是需要存儲庫的類,它們最終將成爲對象圖的網關。
當我第一次瞭解它時,這讓我感到困惑 - 我不認爲識別這些對象會這麼簡單。出路是「Bounded Context」的附加概念。這可能是最不適用的設計原則。
總之,考慮你正在解決以下兩個用戶故事。
- 正如我希望能夠在網站上存儲所有之前的送貨地址,以便我可以下訂單
- 作爲物流管理員時訪問它們更易於用戶想打印出所有地址的,我們需要運送到明天,這樣我可以計劃航線相應
所以,你已經得到的東西像下面的模型:
這似乎很難解剖。如果Person是根,那麼當用戶只是簡單地改變他們的信息時,我們必須用Orders關聯加載Person對象。如果他們下了很多訂單(比如他們爲公司管理庫存),這可能會成爲一個巨大的性能問題。
選擇訂單作爲聚合根也不能解決問題。如果訂單沒有對某人的引用,那麼我們將如何檢查所選地址是否有效?
另一方面:舊學校對這些問題的回答分別是「懶加載」和「雙向關聯」。然而,這些技術都伴隨着他們自己的複雜問題,我相信他們通常比他們的價值更麻煩。
解決這個看似衝突的原因(爲什麼我覺得我在溝通Eliyahu Goldratt?)就是承認這兩個故事存在於不同的意義上下文中。當用戶存儲地址時,他們不關心訂單,同樣,當管理員正在檢查地址時,他們並不關心它的用途。定義有衝突。當兩種情境都說「地址」時,他們指的是相同的物理對象,但只是作爲兩個完全不同概念的試金石!就個人而言,地址只是他們存儲的一個測試塊。就物流經理而言,地址唯一的要求應該是與真實地點相關聯。
那麼爲什麼即使他們是同一個對象呢?
你看到發生了什麼?您已經將問題分解爲兩個離散的和不相關的系統,正如我們現在所知道的那樣,小型,離散和集中的系統是可維護軟件的關鍵。
那麼當這些上下文需要溝通時會發生什麼?由於兩個上下文中的地址對象可能在不同的時間使用(並且其中一個是隻讀的),因此可以使用相同的數據庫。但是,這並不推薦(儘管很多人反正這樣做)。相反,兩個域上下文之間的通信應該通過顯式消息傳遞和映射機制(例如事件聚合器/消息傳遞總線)(如果有人知道兩者之間的區別)來在代碼中處理。
感謝這樣一個徹底的答案:)。 – gmn 2010-08-28 21:22:08