2012-01-19 68 views
5

我最近學會了依賴注入的優點,但是想知道我是否應該在我的項目中使用它,因爲我甚至不需要完整的mvc。現在我正在使用它,我意識到我寫的每個頁面都有額外的開銷。例如...我應該在我的php項目中使用依賴注入嗎?

require_once '../../include/session.class.php'; 
    require_once '../../include/db.class.php'; 
    require_once '../../include/account.class.php'; 

    $objSession = new Session(); 
    $objDb  = new Db(); 
    $objAccount = new Account($objSession, $objDb); 

account.class.php

class Account { 
    ... 
    public function __construct(Session $objSession, Db $objDb) { 
     $this->session = $objSession; 
     $this->db = $objDb; 
    } 
} 

... Account類永遠需要DB和會議,我會永遠只能有一個類各。所以我的問題是,我應該在這樣的情況下使用DI或者我應該只使用...

account.class.php

require_once '../../include/session.class.php'; 
require_once '../../include/db.class.php'; 

class Account { 
    ... 
    public function __construct() { 
     $this->session = new Session(); 
     $this->db = new Db(); 
    } 
} 

...?

+5

依賴注入不僅僅適用於MVC,它是整個項目範圍內的良好實踐,無論您是否使用框架。 –

+1

對不起,並不打算暗示它是,只是這個項目不需要。 – Isius

+0

通過實施自動加載器,您確實可以使代碼變得更加清潔,因此您可以放棄所有要求(當然除了自動加載器的要求)。 – GordonM

回答

6

依賴注入與MVC無關。它使得編寫單元測試更加容易,最終我發現它使我真正思考我正在使用的資源以及該實現是否應該使用該資源。

我個人沒有看到創建注入對象的危害,所以你有幾條線你必須創建一個對象?它告訴用戶更多關於發生了什麼事情。與魔法相比,我寧願清晰。

就我個人而言,我認爲代碼中的大部分混亂來自require聲明。我會說一個自動加載器可以解決這個問題。

我真的很喜歡這個Google Clean Code Talk on DI。它幫助我更好地理解概念及其好處。

+0

我過去曾多次看過Google Talk。這真的很好! – Steven

0

發明了依賴注入容器來解決這個問題。試想一下:

$account = DependencyInjectionContainer::build('Account'); 

DependencyInjectionContainer類將處理注入:

public static function build($class) { 
    switch ($class) { 
     case 'Account': 
      $session = new Session(); 
      $db = new Db(); 
      return new Account($session, $db); 

     // ... 
    } 
} 
1

您已經閱讀了依賴注入的優點。你爲什麼開始使用它?

是否因爲能夠將這些特定的依賴關係替換爲測試或不同的環境?它是否孤立並且明確了循環鏈的順序?

例如,假設它是爲了測試目的而注入不同類的願望(使我使用DI的優點)。如何在沒有DI的情況下處理?

看看你的賬戶類。您可以使用if檢查某個謂詞testMode()來修改構造函數,也可以修改Db和Session構造函數,或者可以更改配置文件。無論您選擇哪種非DI解決方案,您都可以嗎?其他依賴關係(電子郵件發送者,記錄器等)呢?你有沒有與外部系統的接口,你應該模擬測試?

無論如何,答案可能是您沒有DI解決方案就滿意,並且您的應用程序足夠小,無需進行管理。但無論如何,重要的是要問自己這個問題。

同樣,將相同的提問線應用於DI的其他優點,以促使您開始使用它。

順便提一句,你有Db賬戶中的一個實例和另一個在其他類中的另一個實例嗎?你可以只有一個實例嗎? DI有幫助。通過始終注入相同的實例,您可以擁有單例類,而無需實際將它們編碼爲單例。

出於好奇,你爲什麼要做自己的依賴注入而不是使用DI庫?使用DI的一半好處是它可以被其他人的實現完全抽象出來。只編寫你需要的代碼,並讓庫管理你的注射。這與drrcknlsn的建議類似,但是沒有編寫DependencyInjectionContainer類的實際實現:

$ account = DependencyInjectionContainer :: build('Account');

並擰緊其餘部分。

一個好的DI庫應該看到Account的構造函數,意識到它需要一個Db和一個Session,並且繼續構造函數鏈(在這種情況下,因爲它們都有空的構造函數,所以它結束了)。這意味着與非DI案例的代碼量相同(加上構造函數的參數,減去對構造函數的調用,但是頂部沒有額外的廢話),首先帶給你的任何好處。

相關問題