2012-04-14 177 views
1

當您擁有ORM時,存儲庫模式有什麼好處?存儲庫模式與ORM

例子。假設我有以下的(虛構的)表:

表:用戶

pk_user_id 
fk_userrole_id 
username 

表:的UserRole

fk_userrole_id 
role 

現在用的ORM我可以簡單地把這個模型中文件:

$user = ORM::load('users', $id); 

現在$ USER已經是我的對象,它可以很容易地延遲加載:

(如果事情是自動單/多元狀態會更好)

foreach ($user->userroles()->role as $role) 
{ 
    echo $role; 
} 

現在用Repository模式我」 d必須爲用戶創建一個存儲庫,爲角色創建一個存儲庫。存儲庫還需要各種函數來爲我檢索數據並存儲它。另外它需要與實體模型一起工作。所以我也必須創造所有這些。

對我來說,看起來像很多東西做...當我可以簡單地得到像我上面描述的數據與ORM。我可以像存儲它一樣簡單:

ORM :: store($ user);

在這種情況下,它不僅會將用戶對象存儲到數據庫,而且還會對「角色」對象進行任何更改。因此,沒有必要像你需要使用存儲庫模式的任何額外的工作...


所以我的問題主要是,爲什麼我會想使用一個存儲庫模式與ORM?我已經看過教程在哪裏使用該模式(比如Doctrine)。但它對我來說真的沒有任何意義......任何與ORM結合使用的任何解釋.. ??

+0

ORM是一個反模式。 http://seldo.com/weblog/2011/06/15/orm_is_an_antipattern – GordonM 2012-04-14 17:24:17

+0

我真的不能說我同意這個帖子。特別是與現代的手鐲。它爲你延遲關係,你可以很容易地指定你想要的列(如果你需要)。 – w00 2012-04-14 18:45:42

+0

@ w00在你看來,你並不孤單......在這裏可以看到Repository作爲反模式的一些討論:http://ayende.com/blog/3955/repository-is-the-new-singleton – ngm 2012-04-14 19:20:50

回答

3

該ORM是存儲庫的實現細節。 ORM只是簡單地以OOP友好的方式訪問數據庫表。而已。

存儲庫抽象持久性訪問,無論它是什麼存儲。這是它的目的。事實證明,你使用的是db或xml文件或ORM並不重要。存儲庫允許應用程序的其餘部分忽略持久性細節。這樣,您就可以通過模擬或存根來輕鬆測試應用程序,並且如果需要,您可以更改存儲。你可能會使用MySql,明天你會想使用NoSql或雲存儲。用ORM來做!

存儲庫處理域/業務對象(從應用程序的角度來看),ORM處理數據庫對象。業務對象不是數據庫對象,首先是行爲,第二個是榮耀的DTO,它只保存數據。

編輯 您可能會說,存儲庫和ORM都抽象訪問數據,但惡魔是在細節中。存儲庫抽象的接入所有存儲涉及,而ORM抽象訪問特定的RDBMS

簡而言之,存儲庫和ORM的有不同的目的,正如我上面所說的,ORM始終是一個回購的實施細節。

您還可以檢查this post瞭解有關存儲庫模式的更多詳細信息。

0

ORM和存儲庫模式... 取決於設置。

  1. 如果您使用ORM實體作爲域圖層,那麼請不要使用存儲庫。
  2. 如果您有單獨的域模型,並且需要將該模型映射到ORM實體並執行保存操作,那麼存儲庫就是您所需要的。

更多細節,你會發現here(但必須記錄到鏈接)。還要了解差異,請查看存儲庫模式的definition

大多數人使用他們稱之爲庫,而不是在所有的倉庫,只是查詢類類 - 這是怎麼了/你應該把你的查詢,如果你決定去與#1選項(見上面的答案)。在這種情況下,請確保不要從該查詢類中公開DbContext或ISession,也不要從那裏公開CUD方法 - 請記住,Query類!

#2選項是一個艱難的選擇。如果您創建了一個真實的存儲庫,那麼存儲庫接口上的所有輸入和輸出將包含清除的域類(並且不包含與數據庫相關的對象)。禁止從那裏暴露ORM映射類或ORM體系結構相關對象。還會有一個Save方法。這些存儲庫也可能包含查詢,但與查詢類不同,這些回購將會做更多的事情 - 它們將採取您的域聚合(實體的集合和樹)並將它們保存到數據庫,方法是將這些類映射到ORM類並在ORM上執行保存。這種風格(#2)不需要使用ORM,存儲庫模式主要用於ADO.NET(任何類型的數據訪問)。

無論如何,這2個選項是我們可以做的兩個極端。 很多人使用ORM的存儲庫,但他們只是增加了一層額外的代碼,沒有真正的功能,唯一真正的功能就是查詢類的行爲。

另外,當有人談論UnitOfWork時,尤其是使用ORM,我會小心的。幾乎互聯網上的每一個樣本在架構方面都是失敗的。如果你需要UoW,爲什麼不使用TransactionScope(只要確保你有一個默認使用不同於Serializable事務的包裝器)。在99,9%的情況下,你不需要管理2組獨立的數據更改(因此2組OuW),所以TransactionScope在.NET中將是一個很好的選擇 - 對於PHP,我會尋找一些開放會話 - 查看實現...