制御の反転と依存性注入


525

Martin Fowlerが書い論文によると、制御の逆転はプログラムの制御フローが逆転する原理です。プログラマーがプログラムのフローを制御する代わりに、外部ソース(フレームワーク、サービス、その他のコンポーネント)が制御を行いますそれ。何かを別のものに差し込むようなものです。彼はEJB 2.0についての例を述べました:

たとえば、セッションBeanインターフェースは、ejbRemove、ejbPassivate(セカンダリストレージに保存)、およびejbActivate(パッシブ状態から復元)を定義します。これらのメソッドがいつ呼び出されるかを制御するのではなく、何を実行するかを制御します。コンテナは私たちを呼びます、私たちはそれを呼びません。

これは、フレームワークとライブラリの違いにつながります。

制御の反転は、フレームワークをライブラリと異なるものにする重要な部分です。ライブラリは基本的に、呼び出すことができる関数のセットであり、最近では通常、クラスに編成されています。各呼び出しはいくつかの作業を行い、クライアントに制御を返します。

私は、DIがIOCであるという視点は、オブジェクトの依存関係が逆転することを意味します。オブジェクト自体の依存関係、ライフサイクルを制御する代わりに、何か他のことがあなたのために行います。ただし、DIについて手作業で説明したように、DIは必ずしもIOCではありません。それでもDIはあり、IOCはありません。

ただし、このペーパー(pococapsule、C / C ++の別のIOCフレームワークから)では、IOCとDIがあるため、IOCコンテナーとDIフレームワークはJ2EEよりはるかに優れていることを示唆しています。 、したがって、それをプレーン・オールドJava / C ++オブジェクト(POJO / POCO)にしません。

依存性注入パターン以外のコントロールコンテナーの反転(アーカイブリンク)

古いコンポーネントベースの開発フレームワークの何が問題であるかを理解するための追加の読み物。これは上記の2番目のペーパーにつながります。制御の反転の理由と内容(アーカイブリンク)

私の質問:IOCおよびDIとは正確には何ですか?私は混乱しています。pococapsuleに基づいて、IOCはオブジェクトまたはプログラマーとフレームワーク間のコントロールの単なる反転よりも重要なものです。


2
これは、IoC対DI(依存性注入)対SL(サービスロケータ)についての良い記事です:tinyurl.com/kk4be58-URLからの抽出:IoC対DI(依存性注入)?IoCは、フローの制御がクライアントコードから「クライアントのために何かを行う」フレームワークに反転する一般的な概念です。SL(Service Locator)とDI(Dependency Injection)は、IoCに由来する2つの設計パターンです。
Swab.Jat 2014年

私の2セントを追加するために、依存関係の注入がコーヒーショップのテーマでどのように役立つかについて興味がある場合は、ここに記事を書きました:digigene.com/design-patterns/dependency-injection-coffeeshop
Ali Nem


依存関係の逆転:具体化ではなく、抽象化に依存します。制御の反転:メインと抽象化、およびメインがシステムの接着剤である方法。:これらは、このことについて話していくつかの良い記事ですcoderstower.com/2019/03/26/... coderstower.com/2019/04/02/... coderstower.com/2019/04/09/...
ダニエル・アンドレスPelaezロペス

このディープについて読むと、すべてのmartinfowler.com/articles/…
Dushman

回答:


644

IoCは、アプリケーションがフレームワーク内のメソッドを呼び出すのではなく、フレームワークがアプリケーションによって提供される実装を呼び出す、という一般的な用語です。

DIはIoCの一種であり、実装はコンストラクター/セッター/サービスのルックアップを通じてオブジェクトに渡され、オブジェクトは正しく動作するために「依存」します。

たとえば、DIを使用しないIoCは、実装がサブクラス化によってのみ変更できるため、テンプレートパターンになります。

DIフレームワークは、DIを利用するように設計されており、インターフェース(またはJavaの注釈)を定義して、実装を簡単に渡すことができます。

IoCコンテナーは、プログラミング言語の外部で機能するDIフレームワークです。一部では、侵襲性の低いメタデータファイル(XMLなど)で使用する実装を構成できます。いくつかでは、ポイントカットで実装を注入するような通常は不可能であるIoCを実行できます。

このMartin Fowlerの記事も参照してください。


2
答えてくれてありがとう。しかし、もう1つの論文では、IOCを使用すると、IOCコンテナーはEJBよりもはるかに優れていることを示唆しています。一方、Martin Fowlerは、EJBがIOCの典型的な例であると示唆しています。
Amumu

5
EJB管理は、実際にはIoCの典型的な例です。これは、EJBのライフサイクルがプログラマーではなくコンテナーによって管理されているという事実からわかります。コントロールはサーバーに委譲されるためプログラマはEJBインスタンスを作成または破棄しません。それがIoCの概念です。外部コードは、コードが呼び出されるタイミングを制御します。これは通常、ほとんどの場合に行われる処理のです。
brandizzi

2
IoCは、アプリケーションがフレームワーク内のメソッドを呼び出すのではなく、フレームワークがアプリケーションによって提供される実装を呼び出すという意味の一般的な用語です。これについてもっと説明できますか?
Imad Alazani 2013

21
別名ハリウッドの原則、「私たちに電話しないで、私たちはあなたに電話します」。呼び出しをアプリケーションではなくフレームワークに任せます。
Garrett Hall

@ImadAlazani、アプリケーションコードからフレームワークへのコントロールの反転に関する詳細な説明であるGarrettが添付した記事をよく読んでください。
MengT 2014年

210

要するに、IoCはDIを含むがこれに限定されないはるかに広い用語です

制御の反転(IoC)という用語は、当初、フレームワーク全体またはランタイムがプログラムフローを制御するあらゆる種類のプログラミングスタイルを意味していました。

DIに名前が付けられる前は、依存関係を管理するフレームワークを制御コンテナーの反転と呼んでいましたが、すぐにIoCの意味は次第に特定の意味に移行しました:依存関係に対する制御の反転。

制御の反転(IoC)とは、オブジェクトが、作業に依存する他のオブジェクトを作成しないことを意味します。代わりに、必要なオブジェクトを外部ソース(xml構成ファイルなど)から取得します。

依存性注入(DI)とは、オブジェクトの介入なしに、通常はコンストラクターパラメーターを渡し、プロパティを設定するフレームワークコンポーネントによってこれが行われることを意味します。


1
IoCはDepency Inversionの原則の別の用語のように思われますか?
Todd Vance

@ToddVance-はい、IoCとDIPは同じものだと思います。DIPとDIは同じものではありません。IoCはDIなしで実行できますが、DIはIoCなしでは実行できません。
エルジェイ2017

2
@ToddVance-いいえ、DIPとIoCは同義語ではなく、関連もありません。
TSmith 2018年

3
ハ、それが私がこのスレッドにいる理由です... "制御の反転と依存性注入"
Todd Vance

50

ここに画像の説明を入力してください
ソース

IoCI nversion o f C ontrol):-これは一般的な用語であり、いくつかの方法(イベント、デリゲートなど)で実装されます。

DID ependency I njection): - DIはのIoCのサブタイプであるとすることによって実現されるコンストラクタ注入、セッター注入またはインターフェイス注射

ただし、Springは次の2つのタイプのみをサポートします。

  • セッター注入
    • セッターベースのDIは、引数なしのコンストラクターまたは引数なしの静的ファクトリーメソッドを呼び出してBeanをインスタンス化した後、ユーザーのBeanでセッターメソッドを呼び出すことによって実現されます。
  • コンストラクターインジェクション
    • コンストラクターベースのDIは、それぞれがコラボレーターを表す多数の引数を使用してコンストラクターを呼び出すことで実現されます。これを使用して、注入されたBeanがnullではなく、高速に失敗することを検証できます(コンパイル時および実行時ではなく失敗)。アプリケーション自体を起動しながら、我々が得ますNullPointerException: bean does not exist。コンストラクター注入は、依存関係を注入するためのベストプラクティスです。

1
Springがプロパティインジェクションをサポートしていないことは正しくありません。します。そしてそれは悪い習慣だと私は同意する。
kekko12

Spring @Autowiredアノテーションは私の意見ではプロパティインジェクションの方法です
Sajith

49

DIはIoCのサブセットです

  • IoCとは、オブジェクトが、作業に依存する他のオブジェクトを作成しないことを意味します。代わりに、必要なオブジェクトを外部サービス(xmlファイルや単一のアプリサービスなど)から取得します。私が使用するIoCの2つの実装は、DIとServiceLocatorです。
  • DIは、依存オブジェクトを取得するというIoCの原則が、具体的なオブジェクトではなく抽象化(インターフェース)を使用せずに実行されることを意味します。これにより、すべてのコンポーネントチェーンがテスト可能になります。より高いレベルのコンポーネントは、インターフェイスからのみ、より低いレベルのコンポーネントに依存しないためです。モックはこれらのインターフェースを実装します。

IoCを実現するためのその他のテクニックをいくつか紹介します。


IoCがオブジェクトを作成しないことを意味するとは私は思いません。クラスメソッドを直接呼び出すのではなく、インターフェイスメソッドを呼び出す場合-これは制御の反転であり(この場合、呼び出し元は呼び出しコードに依存しないため)、オブジェクトの作成とはまったく関係ありません。IoCのもう一つの例のイベントや代理人である
ユージンGorbovoy

19

すべての回答が理論に重点を置いているので、私は最初のアプローチの例で実証したいと思います:

注文の出荷後にSMS確認メッセージを送信する機能を含むアプリケーションを構築しているとします。SMSの送信を担当するクラス(SMSService)とユーザー入力のキャプチャを担当するクラス(UIHandler)の2つのクラスがあります。コードは次のようになります。

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

上記の実装は間違っていませんが、いくつかの問題があり
ます。-)開発環境で、SMSゲートウェイを使用する代わりにテキストファイルに送信されたSMSを保存して、これを実現するとします。(SMSService)の具体的な実装を別の実装に変更することになります。この場合、柔軟性が失われ、コードの書き換えが強制されます。
-)結局、クラスの責任が混在することになり、私たちの(UIHandler)は(SMSService)の具体的な実装について決して知らないはずです。これは、「インターフェース」を使用してクラスの外部で行う必要があります。これが実装されると、同じインターフェースを実装する別のモックサービスで使用される(SMSService)を交換することにより、システムの動作を変更できるようになります。このサービスは、SMSをmobileNumberに送信する代わりにテキストファイルに保存します。

上記の問題を修正するために、(SMSService)と新しい(MockSMSService)によって実装されるインターフェイスを使用します。基本的に、新しいインターフェイス(ISMSService)は、以下のコードと同じように両方のサービスの動作を公開します。

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

次に、(SMSService)実装を変更して(ISMSService)インターフェースを実装します。

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

これで、同じインターフェースを使用して、まったく異なる実装で新しいモックアップサービス(MockSMSService)を作成できます。

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

この時点で、次のように(UIHandler)のコードを変更して、サービス(MockSMSService)の具象実装を簡単に使用できます。

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

私たちは多くの柔軟性を実現し、コードに懸念の分離を実装しましたが、それでも2つのSMSサービスを切り替えるためにコードベースに変更を加える必要があります。したがって、依存性注入を実装する必要があります。

これを実現するには、(UIHandler)クラスコンストラクターに変更を実装して依存関係を渡す必要があります。これにより、(UIHandler)を使用するコードは、使用する(ISMSService)の具体的な実装を決定できます。

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

これで、クラス(UIHandler)と対話するUIフォームは、使用するインターフェース(ISMSService)の実装を渡す責任があります。これは、コントロールを反転したことを意味します。(UIHandler)は、どの実装を使用するかを決定する責任がなくなり、呼び出し側のコードが行います。DIがその1つのタイプである制御反転原理を実装しました。

UIフォームコードは次のようになります。

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

素晴らしい説明
ZiviMagic

19

IOC(Inversion Of Control):オブジェクトのインスタンスを取得するためにコンテナーに制御を与えることをInversion of Controlといいます。つまり、new演算子を使用してオブジェクトを作成する代わりに、コンテナーにそれを実行させます。

DI(Dependency Injection):オブジェクトにプロパティを注入する方法は、Dependency Injectionと呼ばれます。

依存性注入には次の3つのタイプがあります。

  1. コンストラクターインジェクション
  2. セッター/ゲッター注入
  3. インターフェース注入

Springは、コンストラクターインジェクションセッター/ゲッターインジェクションのみをサポートしています。


5

しかし、春のドキュメントはそれらが同じであると言います。

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

最初の行では、「IoCは依存性注入(DI)とも呼ばれます」。


1
彼らが対処しようとしていたのは、DIがIoC設計パターンの非常に広く使用されているフレーバーであり、ほとんどの場合、IoC aka DIと簡単に呼ばれる可能性があることです。
ha9u63ar

5
「IoCはディペンデンシーインジェクション(DI)としても知られています」...
MikeM 2016年

5

IoC-制御の反転は、言語に関係なく一般的な用語であり、実際にはオブジェクトを作成するのではなく、オブジェクトが作成される方法を説明します。

DI-依存性注入は具体的な用語であり、さまざまな注入技術を使用して、実行時にオブジェクトの依存性を提供します。セッター注入、コンストラクター注入、またはインターフェイス注入。


4

制御の反転は、アプリケーションのターゲットコンポーネント(作業を実行するコンポーネント)にさらに制御を与えることを目的とした設計パラダイムです。
依存性注入は、コンパイル時に他のオブジェクトが依存するオブジェクトのインスタンスを作成するために使用されるパターンであり、コンパイル時にどのクラスがその機能を提供するために使用されるかはわかりません。

制御の反転を実装するには、いくつかの基本的な手法があります。これらは:

  • ファクトリパターンの使用
  • サービスロケーターパターンの使用
  • 以下のタイプの依存性注入を使用:

    1)コンストラクター注入
    2)。セッター注入
    3)。インターフェース注入

4

DIIOCは、主にコンポーネント間の疎結合の提供、または単にオブジェクト間の従来の依存関係を分離して、オブジェクト同士が密にならないようにすることに焦点を当てた2つの設計パターンです。

以下の例では、これらの両方の概念を説明しようとしています。

以前は次のようなコードを書いています

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

依存性注入では、依存性注入器がオブジェクトのインスタンス化を処理します

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

インスタンス化と注入のために他のいくつか(たとえばコンテナー)に制御を与える上記のプロセスは、制御の反転と呼ばれ、IOCコンテナーが依存関係を注入するプロセスは、依存関係の注入と呼ばれます。

IOCは、プログラムの制御フローが逆転する原理です。プログラマーがプログラムのフローを制御する代わりに、プログラムはプログラマーへのオーバーヘッドを減らすことによってフローを制御します。依存関係を注入するためにプログラムが使用するプロセスは、 DI

2つの概念は連携して機能し、より柔軟で再利用可能なカプセル化されたコードを作成する方法を提供します。これにより、オブジェクト指向ソリューションの設計における重要な概念になります。

また読むことをお勧めします。

依存性注入とは何ですか?

私の同様の答えの1つをここで確認することもできます

制御の反転と依存性注入の違い


3

制御の反転は、保守が容易な再利用可能なモジュール式ソフトウェアフレームワークの作成を支援するソフトウェアアーキテクチャの一般的な設計原則です。

これは、フローの制御がジェネリックで作成されたライブラリまたは再利用可能なコードから「受信」される設計原則です。

理解を深めるために、コーディングの初期の頃のコーディング方法を見てみましょう。手続き型/従来型言語では、ビジネスロジックは通常、アプリケーションのフローを制御し、汎用または再利用可能なコード/関数を「呼び出し」ます。たとえば、単純なコンソールアプリケーションでは、制御のフローはプログラムの命令によって制御されます。これには、いくつかの一般的な再利用可能な関数の呼び出しが含まれる場合があります。

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

対照的に、IoCでは、フレームワークはビジネスロジックを「呼び出す」再利用可能なコードです。

たとえば、Windowsベースのシステムでは、ボタン、メニュー、ウィンドウ、ダイアログボックスなどのUI要素を作成するためのフレームワークがすでに利用できます。アプリケーションのビジネスロジックを記述する場合、ビジネスロジックコードを呼び出すのはフレームワークのイベントであり(イベントが発生したとき)、その逆ではありません。

フレームワークのコードは私のビジネスロジックを認識していませんが、コードを呼び出す方法は認識しています。これは、イベント/デリゲート、コールバックなどを使用して実現されます。ここでは、フローの制御が「反転」されています。

したがって、静的にバインドされたオブジェクトの制御フローに依存する代わりに、フローはオブジェクトグラフ全体と異なるオブジェクト間の関係に依存します。

Dependency Injectionは、オブジェクトの依存関係を解決するためのIoC原則を実装する設計パターンです。

簡単に言うと、コードを記述しようとしているときは、さまざまなクラスを作成して使用することになります。1つのクラス(クラスA)は他のクラス(クラスBやD)を使用できます。したがって、クラスBおよびDはクラスAの依存関係です。

簡単な例えはクラスカーです。車は、エンジン、タイヤなどの他のクラスに依存している場合があります。

Dependency Injectionは、Dependentクラス(ここではClass Car)が依存関係(Class EngineおよびクラスTyre)を作成する代わりに、クラスに依存関係の具象インスタンスを注入する必要があることを示唆しています。

より実用的な例で理解しましょう。独自のTextEditorを作成していると考えてください。特に、テキストのタイプミスをチェックする機能をユーザーに提供するスペルチェッカーを使用できます。このようなコードの簡単な実装は次のとおりです。

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

一見、バラ色に見えます。ユーザーがテキストを書き込みます。開発者はテキストをキャプチャしてCheckSpellings関数を呼び出し、ユーザーに表示するタイプミスのリストを見つけます。

1人のユーザーがエディターでフランス語を書き始める晴れた日まで、すべてがうまくいくようです。

より多くの言語をサポートするには、より多くのSpellCheckersが必要です。おそらくフランス語、ドイツ語、スペイン語など。

ここでは、「English」SpellCheckerがTextEditorクラスと密結合している密結合コードを作成しました。つまり、TextEditorクラスはEnglishSpellCheckerに依存しています。つまり、EnglishSpellChekerはTextEditorの依存関係です。この依存関係を削除する必要があります。さらに、テキストエディターには、実行時の開発者の裁量に基づいて、スペルチェッカーの具体的な参照を保持する方法が必要です。

したがって、DIの紹介で見たように、クラスには依存関係を注入する必要があることを示しています。したがって、呼び出されたクラス/コードにすべての依存関係を挿入するのは、呼び出しコードの責任である必要があります。したがって、コードを次のように再構成できます。

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

この例では、TextEditorクラスはISpellCheckerタイプの具象インスタンスを受け取る必要があります。

これで、依存関係をコンストラクター、パブリックプロパティ、またはメソッドに注入できます。

コンストラクターDIを使用してクラスを変更してみましょう。変更されたTextEditorクラスは次のようになります。

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

そのため、呼び出しコードは、テキストエディターの作成中に、適切なSpellChecker TypeをTextEditorのインスタンスに注入できます。

ここで完全な記事を読むことができます


3

IOC(Inversion Of Control):オブジェクトのインスタンスを取得するためにコンテナーに制御を与えることは、Inversion of Controlと呼ばれます。つまり、new operatorを使用してオブジェクトを作成する代わりに、コンテナにそれを実行させます。

DI(Dependency Injection):必要なパラメーター(プロパティ)をXMLからオブジェクト(POJO CLASS内)に渡すことを、依存性注入と呼びます。


2

IOCは、アプリケーションのクラスを管理する外部クラスを示し、外部クラスは、コンテナーがアプリケーションのクラス間の依存関係を管理することを意味します。IOCの基本的な概念は、プログラマーがオブジェクトを作成する必要はなく、オブジェクトの作成方法を説明することです。

IoCコンテナによって実行される主なタスクは次のとおり です。アプリケーションクラスをインスタンス化する。オブジェクトを構成します。オブジェクト間の依存関係を組み立てます。

DIは、セッター注入またはコンストラクター注入を使用して、実行時にオブジェクトの依存関係を提供するプロセスです。


2

IOC(Inversion of Control)は、基本的に、依存関係を削除してフローを非線形にするために分離し、コンテナまたは別のエンティティに依存関係のプロビジョニングを管理させる設計パターンの概念です。それは実際にはハリウッドの校長「私たちに電話しないでください、私たちはあなたに電話します」に従います。違いを要約します。

制御の反転:-依存関係を分離してプロビジョニングを委任することを総称しており、これはいくつかの方法(イベント、デリゲートなど)で実装できます。

依存性注入:-DIはIOCのサブタイプであり、コンストラクター注入、セッター注入、またはメソッド注入によって実装されます。

次の記事では、これを非常にきちんと説明しています。

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

オブジェクト指向の雑草に入らなくても、アイデアを明確に示すことができると思います。

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

頭を傾けて目を細めると、DIはIoCの特定の実装であり、特定の懸念事項があることがわかります。モデルと動作をアプリケーションフレームワークまたは高次の操作に注入する代わりに、変数を関数またはオブジェクトに注入します。


0

SOLIDのDから始めて、Scott Millettの本「Professional ASP.NET Design Patterns」のDIとIoCを見てみましょう。

依存関係の逆転の原則(DIP)

DIPは、すべての具体的な実装からあなたのクラスを分離し、それらを抽象クラスやインターフェイスに依存した程度です。これは、実装ではなくインターフェイスへのコーディングのマントラを促進します。これにより、1つの実装に密に結合されないようにすることで、システム内の柔軟性が向上します。

依存性注入(DI)と制御の反転(IoC)

DIPと密接に関連しているのは、DI原則とIoC原則です。DIは、コンストラクター、メソッド、またはプロパティを介して低レベルまたは依存クラスを提供する行為です。DIと組み合わせて使用​​すると、これらの依存クラスをインターフェースまたは抽象クラスに反転させることができます。これにより、高度にテスト可能で変更が容易な疎結合システムにつながります。

IoC、制御のシステムの流れは、手続き型プログラミングと比べて反転されます。この例はIoCコンテナです。その目的は、クライアントコードに具体的な実装を指定せずにクライアントコードにサービスを注入することです。この場合、制御が反転するのは、クライアントがサービスを取得する行為です。

ミレット、C(2010)。プロフェッショナルASP.NETデザインパターン。ワイリー出版。7-8。


0

// ICO、DI、10年前、これは彼らのやり方でした:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

今Spring 3,4または最新の以下のようなもの

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

全体として、コントロールは、結合されたコードの古い概念から、オブジェクトを使用可能にするSpringのようなフレームワークに逆転します。つまり、私が知る限りこれはIOCであり、従属オブジェクトをConstructorまたはsetterを使用して別のオブジェクトに注入するときの依存関係注入です。注入とは、基本的に引数として渡すことです。春には、Beanオブジェクトを定義し、コンストラクターまたはセッターのインジェクションスタイルで依存オブジェクトを渡す、XMLおよび注釈ベースの構成があります。


0

IzoneとDIの本当の違いを理解するのに本当に役立つDzone.comで最高の例を見つけました

「IoCとは、誰かにオブジェクトを作成してもらうことです。」したがって、コードに "new"キーワード(たとえば、MyCode c = new MyCode())を記述する代わりに、オブジェクトは他の誰かによって作成されます。この「他の誰か」は通常、IoCコンテナと呼ばれます。それは、オブジェクトのインスタンスを取得するためにコンテナにrrsponsibility(control)を引き継ぐことを意味します。これは、コントロールの反転と呼ばれます。つまり、new演算子を使用してオブジェクトを作成する代わりに、コンテナーにそれを実行させます。

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

記事の全文読むIOCおよび記事の全文読むDI


0

1)DIはChild-> objはparent-objに依存します。依存する動詞が重要です。2)IOCは、プラットフォームの下でChild-> obj performです。プラットフォームは、学校、大学、ダンスクラスである可能性があります。ここで実行するのは、任意のプラットフォームプロバイダーで異なる意味を持つアクティビティです。

実用的な例: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

この質問に関しては、ウィキはすでに詳細でわかりやすい説明を提供していると思います。ここで最も重要なことを引用します。

IoCの実装

オブジェクト指向プログラミングでは、制御の反転を実装するためのいくつかの基本的なテクニックがあります。これらは:

  1. サービスロケーターパターンの使用依存性注入の使用(コンストラクター注入など)パラメーター注入セッター注入インターフェイス注入。
  2. コンテキスト化されたルックアップを使用します。
  3. テンプレートメソッドのデザインパターンを使用します。
  4. 戦略設計パターンの使用

依存性注入

依存関係の注入は、1つのオブジェクト(または静的メソッド)が別のオブジェクトの依存関係を提供する手法です。依存関係は、使用できるオブジェクト(サービス)です。インジェクションとは、依存関係を使用する依存オブジェクト(クライアント)に依存関係を渡すことです。


0

IoCの概念は、手続き型プログラミングの時代に最初に耳になりました。したがって、歴史的な文脈から、IoC 制御フローの所有権の逆転について話しました。つまり、それが関数自体であるか、外部エンティティにそれを逆転する必要があるかに関係なく、希望の順序で関数を呼び出す責任を誰が持っているかです。

ただし、OOPが登場すると、制御フローとは別に、アプリケーションがオブジェクトの作成とその関係にも関係するOOPのコンテキストで、IoCについて人々が話し始めました。そのようなアプリケーションは、(制御フローではなく)オブジェクト作成の所有権を逆転させたいと考え、オブジェクトの作成、オブジェクトのライフサイクル、およびアプリケーションオブジェクトの依存関係の注入を担当するコンテナーを必要とし、それによってアプリケーションオブジェクトが他の具象オブジェクトを作成することを排除しました。

その意味では、DIはIo Cと同じではありません。これは、制御フローに関するものではないためですが、一種のIo *、つまりオブジェクト作成の所有権の反転です。

DIとIoCを説明する私の方法の何が問題になっていますか?


0

IoC別名Inversion of Controlは、Springコンテナーによって実行されるインスタンスを作成するコントロールを指します。オブジェクトを作成および構築するためのコントロールは、コンテナーによって処理されます。コンテナーはオブジェクトを作成し、それらをアプリケーションに注入します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.