2012-04-07 71 views
0
public class Widget { 
    @Inject 
    Fizz fizz; 

    public Widget(Fizz fizz) { 
     super(); 

     setFizz(fizz); 
    } 

    public void setFizz(Fizz fizz) { 
     this.fizz = fizz; 
    } 
} 

這是一個Guice反模式?!?!這是一個Guice反模式嗎?

如果我說「fizz將被注入(通過@Inject)」,但然後我允許構造函數和設置器接受一個嘶嘶聲,這是不必要的多餘?它會引起與Guice噴油器的衝突嗎?

我想我很困惑,:

  • 何時應標註屬性與@Inject,與
  • 時候你應該通過構造函數/吸氣自己「注入」屬性

有什麼想法?提前致謝!

+0

不知道爲什麼會發生衝突(我只是不知道),但似乎沒有理由明確禁止在Guice之外設置自己的Fizz,除非這是一個特定的目標。 – 2012-04-07 18:42:25

回答

4

爲什麼不使用這樣的東西(即使用構造函數注入)?

public class Widget { 
    private Fizz fizz; 

    @Inject 
    public Widget(Fizz fizz) { 
     super(); 

     this.fizz = fizz; 
    } 

} 

http://code.google.com/p/google-guice/wiki/Injections

+0

有什麼區別?如果我註釋屬性,而不是構造函數,Guice如何表現不同? – IAmYourFaja 2012-04-07 18:44:35

+0

當類需要多個依賴項時,註釋構造函數一次就可以避免註釋每個字段。 – 2012-04-07 18:46:50

+0

區別在於變量可用的時間。如果你做構造函數注入,你顯然可以在構造函數中使用它們,如果你使用getter/setter注入,注入的成員只有在構造函數完成後纔可用。 – mglauche 2012-04-07 18:46:56

1

見我肯定會說這是一個問題,而不是因爲吉斯不能做到這一點,但因爲你的代碼有缺陷。 Guice將嘗試調用默認的無參數構造函數(不存在)並失敗。

但即使您添加了無參數構造函數,這仍然是一種反模式。我已經使用了DI框架一段時間,從未遇到過需要進行現場注入的情況。我確信這有一個用例,否則Guice人不會包含它,但是如果沒有特殊的代碼,無論是字節碼操作還是反射,都無法測試代碼。

建設者注入通常是最好的,原因有很多。它使任何調用者都清楚地知道你的依賴關係是什麼,它允許你同時初始化所有類的不變量(避免一個部分初始化的類),它是唯一允許你創建不可變對象的DI風格,它是線程安全並降低程序複雜性。

我只用於方法注入的用例是當我不想要一個子類來聲明父類的依賴關係,或者當我想要一個「可選」依賴項時,但這些很少見。

3

您應該使用構造函數注入對於那些REQUIRED依賴。 使用屬性注入當依賴項是可選