2012-01-19 18 views
5

私は最近、依存性注入のメリットを学んだことがありますが、私は自分のプロジェクトでそれを使うべきかどうか疑問に思っています。これを使用しているので、私はそれぞれのページで余分なオーバーヘッドを認識しています。たとえば...私は私の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); 

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

account.class.php ... Accountクラスは常にDBとのセッションが必要になりますし、私は今まで、それぞれの1つのクラスを持っています。 ...だから私の質問は、私はこのような状況でDIを使用する必要がある場合、または私はちょうど使用する必要があります...

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(); 
    } 
} 

account.class.php

+5

依存性注入はMVCだけではなく、フレームワークを使用しているかどうかに関わらず、あらゆるプロジェクトで良い方法です。 –

+1

申し訳ありませんが、このプロジェクトでは必要ないことを暗示するつもりはありません。 – Isius

+0

実際にオートローダを実装するだけで、コードをもっとクリーンにすることができますので、必要なものすべてを省くことができます(もちろん、オートローダの必要は除きます)。 – GordonM

答えて

6

依存性注入は、MVCとは関係ありません。単体テストを書くのが本当に良いですし、最終的に私は使用しているリソースと、その実装がそのリソースを使用する必要があるかどうかを本当に考えていることがわかりました。

私は個人的に注射されたオブジェクトの作成に害を感じないので、オブジェクトを作成する必要がある行がいくつかありますか?これは、何が起こっているかについてユーザにもっと多くのことを伝えます。私はむしろ魔法と比較して明快さを持っています。

個人的には、コードの乱雑さのほとんどがrequireステートメントから来ていると思います。私はオートローダがその問題のいくつかを解決するだろうと言っています。

私は本当にこれを楽しんだGoogle Clean Code Talk on DI。それは私が概念とその利点を少し良く理解するのに役立ちました。

+0

これまでGoogleトークを複数回見てきました。それは本当に良いです! – 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なしでそれをどうやって扱いますか?

あなたのアカウントクラスを見てください。ある述語のtestMode()のifチェックを使ってコンストラクタを変更するか、DbとSessionのコンストラクタを変更するか、設定ファイルを変更することができます。あなたが選んだDIソリューションが何であれ、それで大丈夫ですか?他の依存関係(emailer、loggerなど)はどうですか?テストのために模擬すべき外部システムへのインタフェースはありますか?

とにかく、DIソリューションがなければ満足していて、アプリはそれがなくても十分に管理できるほど小さいという回答があります。とにかく自分自身に質問することが重要です。

同様に、同じ行の質問をDIの他のメリットに適用して、その使用を開始するようにしました。

ちなみに、アカウントにはDbのインスタンスが1つあり、他のクラスにはそれぞれ1つのインスタンスがありますか?インスタンスが1つしかありませんか? DIはそれを助けます。同じインスタンスを常に注入することで、シングルトンクラスを実際にシングルトンとしてコーディングしなくてもシングルトンクラスを持つことができます。

DIライブラリを使用するのではなく、あなた自身の依存関係注入をなぜやっていますか? DIを使用する利点の半分は、他の人の実装によってきれいに抽象化されていることです。あなたが必要とするコードだけを書いて、図書館であなたのために注射をするようにしましょう。これはdrrcknlsnの提案に似ていますが、DependencyInjectionContainerクラスの実際の実装を記述することはありません。

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

と残りをねじ留めします。

良いDIライブラリは、Accountのコンストラクタを参照して、DbとSessionが必要であることを認識し、コンストラクタのチェーンを構築します(この場合、両方とも空のコンストラクタがあるので終了します)。これは、DI以外のケースと同じ量のコード(コンストラクタへの引数からコンストラクタへの呼び出しを除いたものですが、上に余計なことはありません)と同じ意味になります。

関連する問題