我們正準備在我們的保險數據轉換平臺中開始使用Guice,並且我遇到了一個有趣的場景,似乎並沒有在Guice文檔或我發現的任何帖子中直接解決。Guice puzzler:批量作用域封裝上下文
我們的平臺在幾個重要領域使用封裝上下文(EC)模式。例如,假設我們正在處理一組10個策略。無論何時我們開始處理新政策,我們都希望構建一個PolicyContext
對象並初始化諸如保單號,州和公司等屬性。此PolicyContext
是轉換過程中涉及的許多類的依賴項。
請注意PolicyContext
(和我們應用程序中的其他*Context
對象)是一個值集合在特定領域(代表基本的,無所不在的策略信息)的對象。我很想知道你們當中的模特大師是否仍然認爲這是一種反模式(正如Misko Hevery在http://misko.hevery.com/2008/07/18/breaking-the-law-of-demeter-is-like-looking-for-a-needle-in-the-haystack/中所討論的那樣),儘管這些都是純粹的價值對象,當然不代表「廚房水槽」。
目前,我們正在以最糟糕的方式管理PolicyContext
:我們有一個靜態全局變量policyContext
,並且在我們開始處理新策略時調用policyContext.initialize(String company, String state, String policyNum)
。
我的目標是要吉斯在架構優化的方式管理這些上下文對象,這樣,在概念上,每當我們開始處理新的政策:
- 吉斯丟棄舊
PolicyContext
。 - Guice使用來自數據庫的
company/state/policyNum
params構造一個新的,不可變的PolicyContext
(無臭初始化方法)。 - Guice將已構造的
PolicyContext
注入到所有需要它的類中。
這裏是我試探性的方法:
- 創建一個自定義的範圍,一些類似於在http://code.google.com/p/google-guice/wiki/CustomScopes的吉斯批次樣品範圍的--where批次的邊界外部確定。在這個範圍內,在我們開始處理新政策的地方,我們可以1)結束以前的「批次」並開始一個新的政策。 Q:我無法完全按照上述URL中列出的方式使用Guice批量範圍示例?
既然
PolicyContext
沒有依賴關係,我們將使用AssistedInject爲所有構造函數參數(這似乎有點奇怪)。假設我們採取這種做法,並生成一個PolicyContextFactory
,接下去,我們開始處理新的政策,我們將有這樣的代碼:… scope.exit(); scope.enter(); @Inject private PolicyContextFactory policyContextFactory; policyContextFactory.create(company, state, policyNum); // the parameters come from a database record. // Note that we don’t need to actually store the created instance; it will be injected elsewhere into various class constructors. …
這個問題似乎最佳?我知道可能有更簡單的方法(例如,每當我們處理新策略時創建新的PolicyContext
特定注入器,這會有效地創建新的PolicyContext
)。然而,這是架構的核心部分,所以我真的不想妥協。
另一種選擇,我知道,是在這種情況下使用DI棄權,只需使用一個靜態PolicyContextManager
類單獨create
和get
方法,其中,前一種方法是,丟棄當前PolicyContext
並創建工廠/賣場一個新的,而後一種方法只是返回「活動」PolicyContext
)。但是我的代碼最終會做手動DI,因爲我會寫很多代碼,如methodThatNeedsPolicyContext(PolicyContextManager.get(), …)
。既然我們打算開始使用Guice,這種方法似乎並不是最佳的。
順便說一句,對於那些試圖培養DI更深入的瞭解,我深受Dhanji人員Prasanna推薦「依賴注入」。這本關注Guice和Spring的書絕對是不可或缺的,因爲它比我遇到的任何其他東西都要深刻得多。
感謝您的幫助!
非常感謝傑夫。清楚地陳述並解決一些重要的細微差別。我確實有幾個相關的問題,但我會分開發布。 –
+1用於注入提供者並創建自定義範圍。不要以爲你需要綁定才能注入提供商BTW。 – RobbieV
@RobbieV正如我提到的「免費獲得」評論,如果Guice可以注入'Foo',它可以注入'Provider'而不需要額外的代碼。如果它是一個具體類,'Foo'可以被隱含地綁定,不需要綁定'Foo'或'Provider ',但是如果'Foo'是一個接口,你仍然需要將它綁定到某個地方。儘管 - 我已經說過「綁定'Provider '」,我的意思是「注入'Provider 」 - 現在已經修復了。 –