2008-09-24 22 views
6

This question about unit testing best practices提到了爲依賴注入設計類。這讓我想到了這可能意味着什麼。爲依賴注入設計類的指導

剛開始使用控制容器的反轉工作時,我對這個問題有一些想法,所以讓我把它們放在牆上,看看有什麼支持。

我看到它的方式,有一個對象可以有三種基本的依賴類型。

  1. 對象依賴 - 這將有問題的類中使用一個實際的對象。例如LogInFormController中的LogInVerifier。這些應該通過構造函數注入。如果這個類的級別足夠高,以至於它在構造函數中需要超過4個這樣的對象,則考慮將其分解或至少使用工廠模式。您還應該考慮通過接口提供依賴性並對接口進行編碼。
  2. 簡單設置 - 例如閾值或超時期限。這些應該通常有一個默認值,並通過工廠模式的建設者設置。你也可以提供設置它們的構造函數重載。但是在大多數情況下,你可能不應該強迫客戶必須明確地設置它。
  3. 消息對象 - 一個對象從一個類切換到另一個接收類推測用於業務邏輯的對象。一個例子是LogInCompleRouter類的User對象。在這裏,我發現通常最好不要在構造函數中指定消息,因爲您必須使用IoC容器註冊User實例(使其成爲全局),或者在實例化User之後不實例化LogInCompleteRouter (爲此你不能使用DI或者至少需要顯式依賴於Container)。在這種情況下,只有當你需要它進行方法調用時(比如LoginInCompleteRouter.Route(User u);),傳遞消息對象纔會更好。

另外,我要指出,不一切應DI'ed,如果你有功能的簡單一點,這是方便只需分解出一個扔掉的類,它可能是好的實例當場。顯然這是一個判斷呼籲;如果我發現它的權宜之計寫一個類如

class PasswordEqualsVerifier { 
    public bool Check(string input, string actual) { return input===actual;} 
} 

我可能不會打擾依賴注入它,只會有一個對象直接實例它使用塊內。推論是如果值得編寫單元測試,那麼它可能是值得注入的。

那麼你們怎麼看?歡迎任何其他指導方針或對比意見。

回答

1

重要的是嘗試對接口進行編碼,並讓你的類接受這些接口的實例,而不是自己創建實例。你可以明顯地對此發瘋,但無論單元測試還是DI,這都是一個很好的實踐。

舉例來說,如果你有一個數據訪問對象,你可能會傾向於寫這樣所有的DAO基地:

public class BaseDAO 
{ 
    public BaseDAO(String connectionURL, 
        String driverName, 
        String username, String password) 
    { 
     // use them to create a connection via JDBC, e.g. 
    } 

    protected Connection getConnection() { return connection; } 
} 

然而,這將是更好地從有利於類刪除此的接口

public interface DatabaseConnection 
{ 
    Connection getConnection(); 
} 

public class BaseDAO 
{ 
    public BaseDAO(DatabaseConnection dbConnection) 
    { 
     this.dbConnection = dbConnection; 
    } 

    protected Connection getConnection() { return dbConnection.getConnection(); } 
} 

現在,您可以提供DatabaseConnection的多重元素。即使忽略單元測試,如果我們假設我們正在使用JDBC,有兩種方法可以從容器中獲得Connection:連接池,或直接通過使用驅動程序。現在,您的DAO代碼並未與任何一種策略相關聯。

爲了進行測試,您可以製作一個MockDatabaseConnection,將其連接到某些嵌入式JDBC實現與預置數據以測試您的代碼。