2009-05-04 7 views
9

この質問をする別の方法は次のとおりです。Inversion of Controlとは何ですか?OO言語固有のInversion of Controlですか?

IoCのWikipediaの記事が非OOの説明でハイジャックされたため、私はこの質問をします。これは、2007年からdiscussion pageから取られているされています。以前の内容が完全にせせらぎ無意味な「オブジェクト指向」によって引き継がれたよう

は、私は、完全にページを書き換えるために自由を取った...

Inversion of ControlがどのようにOO言語の外で意味を持つのかわかりません。手続き型言語(イベントプログラミングは1つ)で制御を放棄することについての多くの説明が既にあり、純粋に関数型言語は高次関数を持っているので、Inversion of Controlのような概念は必要ありません。

また、Martin FowlerがIoCについて詳述しているarticleでは、OOの例を排他的に扱います。

したがって、IoCはOOの概念だけであり、正確には何ですか?

私にとって、IoCはほとんどのOO言語が課す制限内で関数をデータに変換しようとし、それらの関数をデータとして引数として他の関数に渡そうとします。これはIoCの唯一の部分ではありませんが、その一部があります。

また、オブジェクトのツリーが渡される前に構築および構成されている工場設計パターンもあります。

私にとっては、IoCはOOの概念です。

あなたの回答は何ですか?

答えて

11

あなたは実装上の観点から理論的な問題を見ています。発生する最初の質問はとなるはずです。コントロールは何を反転するのですか

次に、渡されたオブジェクト、メソッド、関数、その他のものは重要ではありませんが、実際にはどのようなコードが実行されるかはわかりません。

つまり、依存性注入を行うと、(リソースの)依存関係の作成と使用の制御が逆転します。

Windows API関数にコールバック関数へのポインタを渡すと、独自のパラメータで関数を呼び出すコントロールを与えることができます。

IoCは単なる理論的な概念であり、当然のことながら、実際にはさまざまな実装が可能です。

7

まあ、 "コントロールの反転"という概念は、関数ポインタを渡す方法があるところではどこにでも当てはまるようです。基本的に、プラグインのコンセプトと、互換性のあるシグネチャを持つDLL(ドライバは、例えば、ドライバを考える)は、IoCの一形態に過ぎません。

しかし、IoCをリッチタイプとコンテナモデルで使用すると、基本的にOO環境に自動的になります。また、OOPの概念は、IoCの概念、特に純粋な仮想クラス(または「インタフェース」とも呼ばれます)を使用して複数の継承をサポートする言語に非常によく対応します。

13

制御の反転は、ほとんどの場合OOの概念ではありません。

IoCが存在し、非OO言語では非常に頻繁に使用されます。たとえば、Cでは非常に一般的です。その主な例はWindows APIです。コールバックで動作するWindows API関数を呼び出すときは、基本的にIoCを最も基本的な形で使用しています。

例えば、EnumWindowsの機能を見てください。これを使用して、関数ポインタ(EnumWindowsProc)をライブラリに渡し、コードはライブラリコード内から実行されます。

これをWikipediaのInversion of Controlの定義と比較してください:「ライブラリプロシージャがユーザプロシージャを呼び出すときに制御が逆転する」

これはまったく同じです。

しかし、IoCは、リッチタイプのシステムとOOPに付属する他の多くのツールを追加すると、非常に強力で柔軟性があり、使いやすくなります。これはより一般的になります。なぜなら、それは "より良い"ものですが、OOPの前に存在していたからです。

+0

リッチタイプのシステムで使用する方が簡単だということに完全に同意します。ファーストクラスの市民としての機能により、それはもっと簡単になります。 – xtofl

1

実際、IoCのOO実装は非常に精巧です。なぜなら、関数はしばしばファーストクラスの市民ではないからです。

Azderが述べたとおり、IoCは多くの理由で使用されています。これらの例のいずれもがオブジェクト指向されていない

//javascript 
document.getElementById("mybutton") 
      .addEventListener( 
       function(e){ alert("buttonPressed") }); 

を派遣I説得するためにここにいくつかを要約します:)

反復

#ruby 
{1,2,3}.each{ |i| puts i } 

#haskell 
map [1,2,3] (\i -> write i) 

//the stl algorithms 
int printint(int i){ return printf("%d", i); } 
std::foreach(onetwothree.begin(), onetwothree.end(), &printi); 

スレッドの作成

CreateThread(NULL, 0, &myFunction, NULL, 0, NULL); 

総合イベント、QED 。

関連する問題