4

據我所知,IoC容器有助於創建應用程序級對象,如服務和工廠。但是,應該手動創建域級對象。 Spring的手冊告訴我們:「通常不會在容器中配置細粒度的域對象,因爲創建/加載域對象通常是DAO和業務邏輯的責任。」控制域對象反轉構造問題

好吧。但是如果我的域「細粒度」對象取決於某個應用程序級對象呢? 例如,我有一個UserViewer(用戶用戶,UserConstants常量)類。 有用戶是無法注入的域對象,但UserViewer也需要IoC容器注入的高級對象UserConstants。

我想從IoC容器中注入UserConstants,但我也需要一個瞬態運行時參數User在這裏。

設計有什麼問題?

在此先感謝!

UPDATE

看來我是不是我的問題不夠準確。我真正需要的是一個例子,如何做到這一點:

創建類UserViewer(用戶用戶,UserService服務),其中用戶作爲參數和服務傳遞從國際奧委會注入的實例。

如果我注入UserViewer查看器那麼如何將用戶傳遞給它?

如果我手動創建UserViewer觀衆然後我如何通過服務呢?

回答

4

這個設計沒有任何問題。您使用的是Factories,它在域中有一條腿,在基礎設施中有一條腿。

您可以手動書寫它們,或者讓容器爲您做,例如溫莎的TypedFactoryFacility

當你的域對象來自持久層時,你可以在那裏插入你的容器來注入他們需要的服務(NHibernate可以做到這一點)。

1

但是,如果我的域「細粒度」對象取決於某個應用程序級別的對象呢?

正是這個被認爲是壞習慣。我想說的問題可能是:

  1. 這些對象有很多,所以可能會有性能和內存問題。
  2. POJO風格是它們可以在所有環境中使用(持久存儲在數據庫中,在業務算法和規則中處理,讀取和設置視圖技術,序列化並通過網絡發送)。在它們注入應用程序級的對象可能會導致以下問題:

    1. 在你的建築,你可能有規則,一些(大多數)應用程序級的對象是可用在一些層,而不是別人。因爲所有圖層都可以訪問pojos,所以規則會被傳遞違反。
    2. 當在另一個JVM中序列化並重建時,應用程序級對象的含義是什麼。他們是沒用的,他們必須改變本地等價...

通常,構成域的POJO是自成一體。他們可以訪問其他pojos(和許多枚舉),就這些。

除了數據,他們有實現的業務規則和算法細節方法(記得分組數據和代碼的面向對象的思想,關於它的工作;-)):

  • 這是特別好,當他們有繼承,因爲這允許通過提供一個不同的實現(10不同的情況下,如果或切換:記住OO?;-))來爲某些pojo定製業務規則。
  • 任何需要訪問應用程序級對象(如訪問數據庫)的代碼都會被取出,例如服務或管理器。但是,該代碼保持高水平,因此可讀性和簡單性,因爲pojos自己負責低層細節(和特殊情況)。

    事實之後,你經常會發現pojo方法被重用,並且由服務或管理者以不同的方式組成。這對於減少重複來說是一個巨大的勝利,方法名稱提供了非常需要的「含義」,併爲模塊新增的開發人員提供了更容易的訪問途徑。

+0

好吧。但是什麼是UserViewer?它是一個域或應用程序對象嗎? 這不是POJO,但它似乎不是一個真正的應用程序服務。 它需要同時訪問應用程序對象和POJO對象。我如何實例化它?或者我應該只通過POJO作爲參數?這通常是不方便的。 –

+0

@Andrey 1.任何代碼都可以使用pojos,應用程序對象也不例外。對於實例,我給出了不同的答案。 – KLE

+1

KLE!起初我沒有明白你的意思,但現在我開始明白了。謝謝! 我還有一個問題:這個POJO +服務模型很好,但是它不是過程和反OOP? –

0

對於您的更新:

創建類UserViewer(用戶用戶,UserService服務),其中用戶被作爲參數傳遞和服務是由國際奧委會注入的實例。

如果我注入UserViewer查看器,那麼如何將用戶傳遞給它?

如果我手動創建UserViewer查看器,那麼如何將服務傳遞給它?

在這種情況下,您需要工廠方法(可能位於您的工廠或定位器上)。它可以看看後面,分開兩部分:

public UserViewer createUserViewer(User user) { 
    UserViewer viewer = instantiateBean(UserViewer.class); 
    viewer.setUser(user); 
    return viewer; 
} 

private <E> E instantiateBean(Class<E> clazz) { 
    // call the IoC container to create and inject a bean 
}