web-dev-qa-db-ja.com

手による依存性注入は、構成と多態性のより良い代替手段ですか?

まず、私はエントリーレベルのプログラマーです。実際、私はA.S.を終えています。学位を取得し、夏の最後のキャップストーンプロジェクト。新しい仕事で、やるべきプロジェクトがないとき(チームに新しい求人を入れるのを待っているとき)、私は待っている間に読んで学ぶための本を与えられました-いくつかの教科書、その他それほどではありません(コード完了のように)。これらの本を読んだ後、私はできるだけ多くを学ぶためにインターネットを利用し、SOLIDとDIについて学びました(私たちはリスコフの置換原理についていくつか話しましたが、他のことはあまりしませんでした= SOLIDアイデア)だから、私が学んだように、私はよりよく学ぶために座って、手作業でDIを利用するためのコードを書き始めました(開発コンピューターにはDIフレームワークがありません)。

物事は、私がやっていることに慣れ親しんでいることに気づきます...そしてそれは、ポリモーフィズムを使用して抽象クラスの構成を使用して過去に行った作業に非常に似ているようです。ここに大きな画像がありませんか?それを超えるDI(少なくとも手作業による)について何かありますか?再コンパイルせずに変更する限り、いくつかの大きなメリットを持ついくつかのDIフレームワークのコードにない構成の可能性を理解していますが、手動で行う場合、上記と異なるかどうかはわかりません...これに関するいくつかの洞察は非常に役に立ちます!

13
Drake Clarris

DIの基本的な考え方は、依存関係を外部からプルするのではなく、単にオブジェクトに依存関係をプッシュすることです。これは、以前は「制御の逆転」とも呼ばれていました。これにより、依存関係をより適切に制御し、最後に重要なことですが、単体テストが簡単なコードを書くことができます。

DIフレームワークは、このアイデアの上にのみ構築され、オブジェクトの依存関係を相互に接続するという面倒な部分を(部分的に)自動化します。そうしないと、手作業で行う場合、大規模なプロジェクトで大量のコードが必要になる可能性があります。

外部構成ファイルとは別に、依存関係を定義するために、最近ではコードアノテーションを使用することもできます。 JavaおよびC#のような言語で。これらは両方の世界の利点をもたらす可能性があります:宣言的なスタイルでの依存関係の配線ですが、コード自体の中で論理的に属しています。私にとって、可能性再コンパイルせずに依存関係を変更することは、実際にはほとんど行われないため(特別な場合を除いて)、それほど価値はありませんが、依存関係をコード内で定義されたクラスやオブジェクトから人工的に分離することがよくあります。

タイトルの質問に戻ると、DIは合成や多態性の代替手段ではありません。結局のところ、この2つで可能です。

21
Péter Török

私がこのトピックについて今まで読んだ中で最高の記事は James Shore's でした。抽象化と多態性の一環として、「 DI by Hand 」を古くからやってきた。だから私がプロの世界に入ってその言葉が投げかけられるのを聞き続けた後、私は言葉shouldの意味と何との間に大きな隔たりがあったそれは実際に意味します:

「依存性注入」は、5セントのコンセプトを表す25ドルの用語です。

それは私のためにすべてを片付けたショアの投稿からです。例えば:

与えられた

_class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}
_

書く代わりに:

_class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}
_

あなたはこのようなものを書きます:

_class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());
_

これにより、Carインスタンスが特定のEngineの詳細を処理する必要がなくなります。自動車はエンジンを必要とするだけであり、基本的なエンジン機能を実装している限り、どれを使用してもかまいません。つまり、Carクラスは特定の実装依存関係に関連付けられていません。実行時に潜在的に他の場所に「注入」されます。

この特定のCarの例では、「コンストラクターインジェクション」と呼ばれるDIのサブタイプを使用しています。これは、依存関係がコンストラクターの引数として渡されたことを意味します。 「セッターインジェクション」などにsetEngine(Engine a)メソッドを使用することもできますが、これらのサブタイプは私には理解しにくいようです。

ただし、もう少し詳しくは、多くのDIフレームワークは、これらのより抽象的に参照されるものの束を相互に接続するためのボイラープレートを提供します。

それでおしまい。

22
Nick

DIとは別に、(xmlを使用して構成する代わりに)ルートアプリケーションにクラス構成構成があります。特に大規模なプロジェクトの場合、クラス構成の構成を整えることができますが、DIまたはIoCフレームワークは必要ありません。これは、DIフレームワークには通常、クラス構成の構成に役立つ自動配線などの追加機能を実装するコンテナーが付属しているためです。私の blog エントリを読んで、このトピックに関する理解を深めることができます。

0

私はここ数年でDIを使い始めたばかりなので専門家ではありませんが、気づいたDIコンテナーのいくつかの便利なテーマ/機能(私は構成/多形の製品とは考えていません) (しかし、私はそれについて修正される可能性があります):

  • オブジェクト作成の中央ハブ
  • スレッドごとにシングルトンを提供する
  • 傍受などのアスペクト指向のテクニック
0
Aaron Anodide