2011-06-01 69 views
11

我聽說「@ImplementedBy是邪惡的」,理由是它打破了DI的概念,並使界面意識到它的實現者。Guice's @ImplementedBy邪惡?在某些情況下是否合適?

在某些情況下這可能是正確的,但是我經常發現它只是導致更乾淨的代碼(沒有長模塊來維護),而不會真正傷害過程中的任何內容。

作爲語用學而不是純粹主義者,您認爲使用@ImplementedBy值得什麼時候?

+11

這與Google的「不要做壞事」的座右銘當然是不相容的嗎? – skaffman 2011-06-01 19:28:12

回答

8

我有同樣的呃,ick,yuck感覺@ImplementedBy但同時,它是非常有用的。 Spring必須掃描您提供的軟件包列表中的所有類。在Guice中,您不必配置要掃描的軟件包列表,並且@ImplementedBy是關鍵(如果不使用Binder綁定的話)。當它在第一個Injector.getInstance上落到你的對象上時,碰到一個接口,然後它使用@ImplementedBy找到默認實現(只要Binder沒有覆蓋該默認實現)。

我們也使用@ImplementedBy。我們發現它非常好用,有點呃,但它工作正常並且工作得很好,而且由於它是DI,所以它不是真的取決於實現,因爲無論如何您都可以用新的覆蓋綁定。

與此同時,接口通常在DI框架中越來越少使用。所有的DAO接口都離開了我們的項目,我們仍然可以交換DAO的模擬對象。 java類是隱式接口,可以在不需要接口的情況下進行模擬。我們現在保留主API的接口使用非常清晰,並且不會將其與實現代碼混淆。對於DAO的我們不再需要這個了。

5

您通常應該更喜歡對即時(JIT)綁定的顯式綁定。顯式綁定允許注入器在注入器創建時抓取依賴關係圖。這允許Guice在缺失或無效的情況下快速失效。使用@ImplementedBy等即時綁定,Guice無法報告問題,直到綁定被執行。

JIT綁定也與PrivateModules/child注入器交互不良。儘管大多數應用程序不應該需要這些功能,但如果每個綁定都屬於特定模塊,那麼這樣做並不那麼痛苦。

2

我可以看到谷歌爲什麼做了他們所做的事情,但有一個首選的東西實施並不一定是邪惡的。注意文檔說它是爲默認執行,而不是只有之一。

順便說一句,我發現這個問題,因爲我在因特網上尋找@ImplementedBy概念的現有實現。

我創建了一個名爲@ImplementedBy的註釋,放置在我的一個接口上。當使用純粹的未注入反射時,這是告訴接口要使用什麼實現的最簡單方法,特別是在處理僅理解接口的現有API時。 (接口,不是實現)

這個註釋允許我在裝飾器中用一行註釋和一行代碼將一些非常粗糙的生成器泛化。我不必爲這種簡單的操作使用依賴框架。

4

當一個接口不打算具有多個實現,但必須成爲依賴注入過程的一部分時非常有用,因爲它具有必須由框架注入的依賴關係。

0

對我來說,是的,如果你使用它來硬連線綁定並且永遠不會重複使用綁定是邪惡的,因爲你反轉了界面的感覺。我同意@thSoft這是一個很常見的模式,但對我而言甚至不清楚,爲什麼我們沒有註解。 另外,它可能令人惱火的是,給定的默認實現不是在運行時使用的實現。

只是要清楚什麼google sayed to that

Annotate types tell the injector what their default implementation type is. … 

!它也忽略了通用接口,如

@ImplementedBy(MyImpl.class) 
public interface MyInterface<SIn,SOut> {} 

public class MyImpl implements MyInterface<String, Integer> {} 

通常不會只實現一次。 查看Inject Generic Implementation using Guice瞭解詳情。

+0

沒有@ @ Implements的原因是它沒有任何意義:1.可能有多個類用'@Implements(MyInterface.class)'註解,然後你就會丟失。更糟糕的是,爲了找到實現,你必須首先加載所有的類。 +++關於泛型,我猜'@ ImplementedBy'只是簡單用法的一個捷徑,所以它足夠好。 AFAIK,沒有辦法使用'TypeToken'作爲註解參數。 – maaartinus 2017-11-15 04:10:02

相關問題