2013-03-03 166 views
0

以下代碼有什麼問題?IoC和依賴注入

public class DeDoper { 
    public boolean wackapediaOkToday() { 
     DnsResolver resolver = ResolverFactory.getInstance().makeResolver(); 
     return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9"); 
    } 
} 

爲什麼這個版本首選?

public class DeDoper { 
    @InjectService 
    private DnsResolver resolver; 

    public boolean wackapediaOkToday() { 
     return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9"); 
    } 
} 

我可以很容易模擬ResolverFactory.makeResolver(),這是與設置旋轉變壓器是最新的例子。

這是在this article從ProQuest.biz說:

此[首頁]版本WackapediaOkToday是非常嚴格意義上「注入」了的DNSResolver(雖然這是無可否認不太像得到了一槍,更像是向服務員詢問支票)。但它確實解決了測試問題,並解決了「烏龜一路下山」的問題。

鏈接到工廠 但是在這個[第一版本]方法中,我們實際上是「鏈接」到Factory類的。 (更糟糕的是,如果我們的工廠創建的對象輪流依賴,我們可能不得不在工廠中引入新的工廠)。我們還沒有完全「顛倒」我們的控制,我們仍然從內部調用(控制)工廠我們的課程。

我們需要的是一種完全擺脫我們課程控制的方法,讓他們告訴他們所得到的(他們的依賴)。

回答

2

比方說,你有一個可以有多個實現的服務,如「FileLocator」。它有一個FilesystemFileLocator,它將文件根目錄的路徑和S3FileLocator作爲參數,S3FileLocator將S3憑證作爲參數。前者將要求你編寫一個服務定位器來確定你想要的版本,然後返回它。反過來,這些代碼必須去獲取你的數據,建立適當類型的文件定位器等。你正在做IOC容器應該爲你做的事情。最重要的是,你已經注入了對特定創建方法的依賴。

在第二個版本中(通過註釋或XML)定義了您想要的文件定位器類型。 IOC容器爲你實例化和管理它。這是更少的代碼,你必須維護。如果你想引入第三種類型的FileLocator,那麼它的工作量也會減少。或者,也許你重構你的代碼,所以文件定位器是單身人士,或者如果他們是單身人士,他們現在是工廠的新定位器,或者你想要池定位器實例。在所有這些情況下,如果您使用IOC容器,將會減少破損。