2011-11-25 106 views
9

我總是面臨一個問題,我無法真正想到封裝許多DAO方法的服務對象。DAO和服務?

我的意思是說,對於我的servlet有時使用單個DAO方法就足夠了,例如addUser(User params)。

什麼是更好的做法 - 用服務對象封裝DAO方法並僅使用服務對象總是,即使它的字面意思是單一服務方法調用單一的dao方法或將它們的使用混合在一起(某些服務對象和某些方法從servlet上下文中的dao) - 這意味着我在控制器內部有自動裝配的DAO和服務對象?

如果我開始在同一地點同時使用DAO和Service對象,它會混合邏輯嗎?

回答

6

我認爲這取決於情況。如果沒有DAO將導致混合你的業務邏輯和你的數據訪問邏輯,那麼最好有單獨的類。但是,如果你的DAO是「dummy」並且只是調用一個EntityManager方法,你可能直接在你的服務對象中使用它。這個想法是有single responsibilities並且很容易擴展和測試的類。你不應該爲了它而創建圖層。

如果你想保留一個可重用的服務層,我可能不會直接從你的控制器使用DAO。如果DAO沒有意義,我寧願在服務層使用EntityManager(或者你正在使用的任何持久性策略)。

+0

你是什麼意思,如果它是假的?我雖然這應該是怎麼回事? DAO必須儘可能簡單和虛擬?如果您製作複雜的DAO,那可能是您已經混淆了業務邏輯? – Aubergine

+2

如果您有一個簡單地調用EntityManager的方法的DAO,那麼爲什麼您需要DAO?爲什麼不直接使用EntityManager?我會使用一個DAO,例如,如果我想使用標準API來構建一個查詢,這可能需要很多行,而且我不想混入我的業務邏輯。 –

+2

我感覺我在談論不同的事情,我正在考慮一個案例:我們有DAO有一些訪問數據庫的方法。我們有服務對象單一方法,它只使用單個方法從這個DAO執行它的工作。當我們可以直接使用DAO方法時,在僅使用單個DAO方法的服務對象中創建單個方法是否可行?你會談論同樣的事情嗎?我有很多'EntityManager'方法。 – Aubergine

3

就我個人而言,我通常在服務內封裝DAO調用。

這使我可以使用AOP/etc來完成所有的事務處理。並在這些服務中使用非事務性DAO方法。

對於瑣碎的服務,這是一個額外的「層」,但IMO服務於一個目的(無論如何都可以使用這種或那種代碼生成)。儘管如此,我也很少有 DAO功能包含在服務中。

4

我正在使用「你不能讓控制器與DAO交互的系統」。設計理念被接受,併爲每個組件創建服務層。正如你所描述的,大多數服務只是委託給一個DAO。我反對這個理念有兩個原因。

一個是好老「你不會需要它」。在你需要之前不要實施某些東西。僅僅因爲你預見到了一些額外的間接層來做一些額外的邏輯的理由,它並不確定你會需要它。當你最終需要它時,你可能會發現你的期望並不符合你以前的看法。而且你會得到額外的成本,因爲現在你必須單元測試兩個類而不是一個,而且你需要在兩個地方添加方法而不是一個。

第二個問題,無論如何這是一個服務?當我對域進行建模時,我試圖用面向對象的術語進行思考。有用戶,因此用戶類是有道理的。有新聞項目,因此NewsItem類是有意義的。但我甚至不知道UserService應該做什麼。爲用戶包含「業務邏輯」?不,這就是User類的用處。

如果您需要爲「外部世界」維護一個嚴格的API,那麼我可以看到一個案例有一個保持不變的額外層。但在其他所有情況下,你都不需要它。

+1

我覺得你在這裏拉伸YAGNI。按照你的邏輯,你應該從發起servlet查詢開始並且沒有任何DAO。我們不應該爲維護編寫代碼,因爲您現在還沒有遇到過。如果您的項目有多個服務只是將調用委託給DAO,那麼我認爲在開發中存在嚴重缺陷。應該有一個共同的服務和Dao來處理普通的CRUD。我同意你的OOPS概念,但是我們在名詞王國(請查看http://goo.gl/EAZbX)。你可以說,我們可以做到這一點,但不是沒有調試成本,有時代碼重複。 – Adi

+1

@Adi:我承認我有點極端,但問題是關於服務何時委託給DAO,我覺得有人必須扮演魔鬼的擁護者。 servlet之所以不直接觸發查詢,是因爲我也相信單一責任原則。我認爲我對「服務」的厭惡是我看到的例子中有90%不是將一個調用委託給另一個對象,就是包含更適合於真實域對象的邏輯。哦,我喜歡閱讀葉戈的帖子,即使我不同意。 :) – waxwing

+0

你有我的投票:) – Adi

3

取決於。到單獨的DAO和服務層的原因往往是:

  • 技術限制(參照對方的回答AOP交易)
  • 架構約束(DTO的< => @Entities服務層和DAO之間變換)
  • 歷史(這是怎麼了正在爲X年完成)
  • 審美(只具有從視圖層訪問一層)

使用Java EE 6(JBoss AS中7 ),我沒有這些負擔:

  • 沒有AOP - @Stateless和@Transactional負責處理事務。
  • 沒有DTO - 我使用@Entities從JPA直到視圖層。
  • 不關心歷史。
  • 而且我更喜歡簡單/較少代碼而非美學。

所以我在DAO層有大多數方法。 對於某些情況下,更復雜的操作,我創建一個服務bean,並可能使用extended persistence context

我的經驗法則,一個方法是否應該進入一個服務豆:

  1. 如果使用多個DAO(顯然)
  2. 如果執行幾個實體管理器調用
  3. 如果實現可能會改變,例如在JPQL與Hibernate Search與ElasticSearch之間進行搜索。