2009-07-21 160 views
2

我已經採取了冒險和使用Guice爲我的最新項目。總的印象是好的,但我遇到了一個我無法理解的問題。獲取Guice從愚蠢的數據對象創建對象

背景:這是一個Java6應用程序,通過網絡接受命令,解析這些命令,然後使用它們修改一些內部數據結構。它是我們公司生產的一些硬件的模擬器。我對內部數據結構所做的更改與命令對真實硬件的影響相匹配,因此後續對數據結構的查詢應該基於先前運行的命令反映硬件狀態。

我遇到的問題是命令對象需要訪問這些內部數據結構。這些結構由Guice創建,因爲它們根據所模擬硬件的實際情況而有所不同。命令對象不是由Guice創建的,因爲它們本質上是愚蠢的對象:它們接受一個文本字符串,解析它並在數據結構上調用一個方法。

我唯一能做的就是讓這些命令對象由Guice創建並通過注入傳入數據結構。它感覺真的很笨重,並且完全膨脹了數據對象的構造函數。

我在這裏錯過了什麼?

回答

1

依賴注入最適用於配線服務。它可以用來注入值對象,但這可能有點尷尬,特別是如果這些對象是可變的。

也就是說,您可以使用Providers和@Provides方法來綁定自己創建的對象。

+0

如果您的值對象根據所模擬的硬件而不同,您可以編寫一個工廠來創建它們並讓Guice將工廠注入需要它的代碼。換句話說,避免注入值對象的一種方法是創建一個生成值對象的服務。 – NamshubWriter 2009-07-22 14:36:09

0

假設對一個命令的響應與對http請求的響應沒有什麼不同,我認爲你會走向正確的道路。

http應用程序中常用的模式是將應用程序的邏輯封裝爲具有來自請求和一些後端注入參數的短期對象。然後你實例化這樣的對象並調用一個簡單的,無參數的方法來完成所有的魔法。

也許範圍可以啓發你莫名其妙嗎?看into documentationsome code examples閱讀技術細節。在代碼中,它看起來更像這樣。以下是這可能會爲你的工作情況:

class MyRobot { 
    Scope myScope; 
    Injector i;  

    public void doCommand(Command c) { 
     myScope.seed(Key.get(Command.class), 
     i.getInstance(Handler.class).doSomething(); 
    } 
} 


class Handler { 
    private final Command c; 
    @Inject 
    public Handler(Command c, Hardware h) { 
    this.c = c; 
    } 

    public boolean doSomething() { 
    h.doCommand(c); 
    // or c.modifyState(h) if you want c to access internals of h 
    } 
} 

有些人看不慣這種解決方案,但我已經在代碼嚴重依賴於吉斯在過去的至少兩個不同的項目,看到了這一點。

當然你會在構造函數中注入一些有價值的對象,但是如果你不把它們看作值對象,而是改變它的行爲的類的參數,那一切都是有道理的。

這有點尷尬,有人對這種方式注入價值對象感到fr然心動,但我在過去曾經看到過這種在很久以前就非常依賴Guice的項目,而且效果很好。