2009-02-26 5 views

答えて

9

は、Martin Fowler氏から、この優れたarticleの読み取りを持っています。

また、wikipedia articleをご覧ください。

public interface Reader {} 
public class FileReader implements Reader {} 
public class Application { 
    // flexible abstract dependency injected in 
    private Reader reader; 

    public Application(Reader reader) { // constructor injection 
     this.reader = reader; 
    } 
    public void setReader(Reader reader) { // setter injection 
     this.reader = reader; 
    } 
} 
+1

ツールキット== quickDraw。 – duffymo

+0

(バレルから吹き飛ばす) – toolkit

+0

huh?それは内側の冗談ですか? –

4

いいえ、IoCのはDDDやTDDではありません。

public class FileReader { } 
public class Application { 
    // inflexible concrete dependency 
    private FileReader fileReader = new FileReader(); 
} 

へ:

依存性の注入は、要するにこのことから、あなたのコードをオン制御の反転、の最もよく知られた例であります。

Martin Fowler氏のarticleは良いイントロです。 IOCは何であるかについてのご質問については

+0

100%で同意するが、良いTDDの場合はIOCがほぼ必須である。 ;-) –

+0

申し訳ありませんが、間違っています。他の答えに加えることを意味する。 –

+0

いいえ、私は現場にいましたので、私は今日、私が総ドルであることを証明するコメントを追加しています。 –

1

、ウィキペディアはfairly extensive explanationを持っています。

チュートリアルや例についてthisチュートリアルでは、非常によく、それをカバーし、exmapleコードの多くを持っています。

+0

+1、DeMarcoの引用用です。 – duffymo

12

IOC、又は制御の反転であり、ほとんどのアプリケーションにおいて、UIからデータベースにコードを介してルートを反転します。これは完全な答えではありませんが、コンセプトの周りに頭を浮かべる最も簡単な方法の1つです。

あなたがIOCを勉強したい場合は、設定すると、あなたが反転したら、非常に簡単にテスト見つかりますように、TDDに入ります。

例:私が見た中で最も.NETアプリケーションの

典型的な流れは次のようなものです:

UserCollection col = BusinessLayer.Class.GetLoggedInUsers(); 
//Business logic 
return col; 

、その後の事業は、このようなものです:

など
UserTable table = DataLayer.Class.GetLoggedInUsers(); 
return table; 

これがすべてです擬似コード。この例でIOCを使用するには、IUserRepositoryのようにデータレイヤークラスのインターフェイスを追加します。ジェネリックを使うことができ、私はボンネットの下にお勧めします。

IUserRepository repository = SetUpRepository(); 
UserCollection col = BusinessLayer.Class.GetUsers(repository); 

なぜこれが重要です:あなたは、このような何かを行うことができ

?テストのために、モック・リポジトリを作成し、それをビジネス・クラスに送ることができます。モックには常に同じデータが含まれています。つまり、エンド・ツー・エンドでテストするのではなく、コードを実行しているということです。

あなたがC#のをしたい場合は、ここでweblogs.asp.net上の基本的な例である:

0

あなたはDIP(依存反転原理を)理解していれば、IOCはケーキです。パターンを学ぶ前に、オブジェクト指向の原則を学ぶことをお勧めします。すべてのパターンを達成するために、基本原則をレゴのように積み重ねることができます。専門用語を話すためにBrandon Joyce

7

、制御の反転は、とりわけ、単一責任の原則をサポートしたパターンです。

なぜこのすべてが便利なのかを知るには、いくつかの説明会が必要です。

シングル責任は基本的に、あなたのクラスは、他の一部を変更することの影響を最小限に抑えるために、可能な限りシステムの他の部分から独立したようでなければならないことを意味します。 (たとえば、C/C++プロジェクトで.hファイルを変更する場合など、インプリメンテーションを変更してもプロジェクト内のすべてのファイルが再コンパイルされないようにすることもできます)。 副作用は、1つのことを行うだけの小さなオブジェクトで終わることですが、(理想的な世界では)非常によくなります。

ほとんどの場合、1つのオブジェクトが話す必要があります他のオブジェクト:それはそれらに依存します。

インタフェースから実装を分離するための最初の部分です。それは、あるオブジェクトが別のオブジェクトの特定の実装に結びついていないように、インターフェイス(またはあなたの選択言語に応じて純粋に抽象クラス)に依存することを意味します。

ので、標準的な例を使用するために、ビジネス層のニーズに、あなたは へのアクセスを必要とする機能を実行するために必要がある - オブジェクト を取得するために、データ層を - いくつかの他のサービス - 情報をログに記録するロガーとかエラー

また、すべてのサービスまたは依存関係には独自の依存関係があります。これらの依存関係は、クラスを使用していなくても意識する必要があります。 参照の量に応じて、オブジェクトを設定すると手のひらを素早く出すことができます。今、あなたが書く必要があるクラスの数でそれを掛け、あなたは物事の混乱に終わります。

IOCコンテナを使用すると、基本的にその混乱を取り除くのに役立ちます。 オブジェクトが必要なときは、「新規作成」しないでください。代わりにIOCコンテナにあなたのためにそれを取得するように頼みます。 コンテナは、その依存関係が何であれ、使用の準備ができている機能オブジェクトを配信する責任があります。それが何を意味するのか

は、あなたのクラスがもつれが削減それが依存するクラスの依存関係を意識することの必要がないということです。 さらに、実際のクラスが依存しているサービスをどのように実装しているのかを知る必要はありません。 - サービスの実装は別のプロジェクト(dllなど)で定義できるため、クラスを変更しても影響はありません。 - 実装コンテキストに応じて異なるものにすることができます(データベースの変更やWebサービスの設定やアプリケーションの現在の状態によって情報を取得することなど)。

他の質問にお答えするために、IOCはパターンです。 TDDとDDDは設計方法論であるため、他のものと同等にすることはできません。 しかし、IOCはTDDまたはDDDをサポートする貴重なツールです。

私は頭字語のスープを知っています。あなたが見つけることができる部分サンプルはgrokには簡単ではありません。私があなたに与えることができる最高のアドバイスは、小さなプロジェクトを試してみることです。あなたが仕事のためにそれを見ているならば、簡単な方法ではなく、個人的な観点から見れば、それは絶対に価値があります。

ほんの少し役に立ちます。

0

制御反転は論理構造の抽象化である。 1つのアプローチ(IoCと同義語としてよく使用される)は、オブジェクト間の参照を抽象化するDependency Injectionです。どのクラスがどのサービスを実装するかなど、アプリケーションの実装の詳細からオブジェクトを解放すると、コア関数に自由に集中できます。

たとえば、FooオブジェクトをBarオブジェクトにマップする必要があるクラスがあるとします。

public class FooMapper 
{ 
    public Bar Map(Foo foo) 
    { 
     // ... 
    } 
} 

をし、このようにそれを使用する:あなたはこれを書くかもしれません

public class NeedsToMapFoos 
{ 
    public void MapSomeFoos() 
    { 
     var fooMapper = new FooMapper(); 

     // ... 
    } 
} 

有効なものの、これも剛性です。 NeedsToMapFoosは、というマッピングがであることを気にしていますが、それは特定の方法で発生するものではありません。

public interface IFooMapper 
{ 
    Bar Map(Foo foo); 
} 

をし、その操作への依存を宣言します:

私たちは、インターフェースで「操作のsansの実装」の概念を表すことができ、今

public class NeedsToMapFoos 
{ 
    private readonly IFooMapper _fooMapper; 

    public NeedsToMapFoos(IFooMapper fooMapper) 
    { 
     _fooMapper = fooMapper; 
    } 

    public void MapSomeFoos() 
    { 
     // ...use _fooMapper... 
    } 
} 

NeedsToMapFoosはそれを意味し、少ない知識を持っていますあまり複雑ではありません。管理上の任務を実行する代わりに、ビジネスケースに集中することは自由です。

このようなよく似たオブジェクトも、より適応性があります。ダイヤモンドは硬質で、粘土は可鍛性であるのと同様に、内部構造は変化に対する応答を決定します。

最後に、このスタイルで記述されたロジックも柔軟です。たとえば、FooMapper.Mapが高価な操作であり、キャッシュする必要があるとします。あなたは、既存の実装をラップし、シームレスNeedsToMapFoosにそれを渡すためにDecoratorパターンを使用することができます。

public class CachingFooMapper : IFooMapper 
{ 
    private readonly IFooMapper _innerMapper; 
    private readonly IDictionary<Foo, Bar> _cache; 

    public CachingFooMapper(IFooMapper innerMapper) 
    { 
     _innerMapper = innerMapper; 
    } 

    public Bar Map(Foo foo) 
    { 
     // Read bar from _cache. If not there, read from inner mapper and add to _cache. 
    } 
} 

// Usage 

new NeedsToMapFoos(new CachingFooMapper(new FooMapper())); 
関連する問題