Repository 資源庫模式

這些內容來自 (英)Martin Fowler   的 《企業應用架構模式》。

協調領域和數據映射層,利用類似於集合的接口來訪問領域對象。 

具有複雜領域模型的系統常常受益於一個層,比如由數據映射器提供的層,它分離了領域對象和數據庫訪問代碼的細節。在這種系統中,有必要在集中了查詢構造代碼的映射層之上建立另外一個抽象層。當存在大量的領域類或者繁重的查詢時,這樣做就顯得更重要。在這些特定情況下,增加該層可以使重複的查詢邏輯最小化。

資源庫協調領域和數據映射層,起到類似內存中領域對象集合的作用。客戶對象以陳述的方式構建查詢說明,並把它們提交給資源庫以獲取滿足條件的對象。可以向資源庫中增加對象,也可以從資源庫中刪除對象,就像這些對象來自一個簡單的對象集合,並且由資源庫封裝的映射代碼將根據實際情形執行相應的操作。從概念上來說,資源庫封裝了保存在數據存儲中的對象集以及在這些對象上執行的操作,提供一個更加符合面向對象觀點的持久層實現。資源庫也支持在領域和數據映射層之間實現徹底分離和單向以來關係的目標。

 

運行機制

 

資源庫是使用了本書中大量其他模式的一種高級模式。事實上,資源庫看上去像面向對象數據庫的一小塊,從這個角度來說,它類似於查詢對象,在此情況下開發小組往往會使用對象-關係映射工具而不是親自創建它們。然而,如果開發小組已經採取了這一步,並創建了查詢對象,則增加資源庫功能就不難了。當和查詢對象一起使用時,資源庫不用增加很多操作就可以爲對象-關係映射層添加很大程度的可用性。

不考慮隱藏在後臺的所有機制,資源庫表現爲簡單的查詢接口。客戶創建一個條件對象指定他們需要由查詢返回的對象的特徵。例如,要根據姓名來查找 Person 對象,首先創建一個條件對象,把每個單獨條件設置成如:criteria.equals( Person.LAST_NAME, “Fowler”),及criteria.lik( Person.FIRST_NAME, ‘M’) 。然後調用repository.matching(criteria ) 返回一個領域對象的列表,該列表表示所有姓爲 Fowler,名字已  M 開頭的人。可以在一個抽象的資源庫上定義各種類似於 matching( criteria ) 的便利方法;例如,當只需要一個匹配的對象時,soleMatch( criteria ) 可返回查找到的那個對象而不返回集合。其他常見的方法包括byObjectId( id ),它可以通過簡單的調用 soleMatch 來實現。

對於使用資源庫的代碼而言,資源庫看起來像一個簡單的內存領域對象集合。領域對象本身通常不會直接存儲在資源庫中,這一事實並沒有暴露給客戶代碼。當然,使用資源庫的代碼應該清楚,這個表面上的對象集合可能實際上映射爲一個具有成百上千記錄的產品表。在目錄系統的 ProductRepository 上調用 all() 方法未必是一個好方法。

資源庫用一個基於規約的對象選擇方法來取代基於數據映射器類的特殊的查找器方法。這種方法與直接使用查詢對象相比,後者的客戶代碼可能建立一個條件對象(規約模式的一個簡單例子),在查詢條件中直接提供 all() 函數,並執行查詢。有了資源庫,客戶代碼創建條件,然後把它們傳遞到資源庫,由資源庫選擇其中和條件匹配的對象。從客戶代碼的角度來說,不存在查詢“執行”的概念;但是要根據滿足查詢對象規約的條件來選擇適當對象。這看上去或許只是術語上的差別,但是它闡明瞭對象與資源庫進行交互的好處,這也是其概念威力的一個很大部分。

在外表之下,資源庫把元數據映射和查詢對象結合起來,自動由條件生成 SQL 代碼。無論條件是否知道如何把自身增加到查詢中,查詢對象都知道怎樣合併條件對象,或者由元數據映射自身控制交互是實現的細節。

資源庫的對象源可能根本不是關係數據庫,這也沒有問題,資源庫能順利通過特定的策略對象取代數據映射部分。因爲這個原因,資源庫對存在多數據庫方案或者領域對象源的系統十分有用。另外,在以排他方式使用內存對象的測試代碼中,有望獲得比較快的速度。

資源庫可以成爲一種改善代碼(這種代碼會廣泛使用查詢)可讀性和清晰性的好機制。例如,一個以具有許多查詢頁面爲特徵的基於瀏覽器的系統需要一個簡潔的機制來處理由 HttRequest 對象得到的查詢結果。如果不能自動轉換,該請求的處理程序代碼通常能在不帶來較多混亂的情況下把 HttpRequest 對象轉換爲條件對象;把條件提交給適當的資源庫僅僅需要增加額外的一行或者兩行代碼。

 

使用時機

 

在需要領域對象類型和許多可能查詢的大型系統中,資源庫減少了用於處理所有要執行查詢的代碼總量。資源庫改進了規約模式(這裏以條件對象的形式),規約模式以純面向對象的方式封裝了要執行的查詢。因此,可以刪除所有對特例建立查詢對象的代碼。客戶從來不比考慮 SQL,而僅僅根據對象來寫代碼。

然而,在多數據源的情況下將真正看到資源庫的作用。例如,假設有時我們想使用簡單的內存數據存儲,通常是在爲了獲得較好性能而想完全在內存中運行單元測試的時候。沒有數據庫訪問時,許多長德測試包運行的比較快。爲單元測試創建固定的構件 ( fixture ) 同樣比較簡單,如果所做的只是構建一些領域對象並在建立時把它們放置在集合中,而不是保存在數據庫中並在析構時刪除它們。

當一個應用程序正常運行時,某些領域對象的確定類型應該一直被保存在內存中,對這種情況也可以考慮使用資源庫。不變領域對象(那些不能被用戶改變的對象)就是這樣一個例子,這種對象一旦進入內存,就會一直保留在裏面而且不會被再次查詢。就像我們在本章後面將看到的,一個簡單的資源庫模式的擴展允許根據情況採用不同的查詢策略。

另外一個可以使用資源庫模式的例子是當把數據輸入當作領域對象源使用的時候,比如,互聯網上的一個 XML 流(或許使用 SOAP)可以作爲一個源使用。一個 XMLFeed RepositoryStrategry 可能被實現,它從 feed 中讀取輸入並從 XML 中創建領域對象。

資源庫模式的兩個特點: 

行爲類似內存中的集合

查詢規約提交到資源庫

發佈了18 篇原創文章 · 獲贊 26 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章