制御の反転はオブジェクト指向言語に固有ですか?
-
03-07-2019 - |
質問
この質問をするもう1つの方法は、あなたによると、Inversion of Controlとは何ですか?
この質問は、 IoC のWikipedia記事が非OOによってハイジャックされたためです。説明。これは、ディスカッションページからのもので、2007年のものです。
以前のコンテンツは無意味な「オブジェクト指向」によって完全に引き継がれたため、私は自由にページを完全に書き換えました。せせらぎ...
OO言語以外では、Inversion of Controlがどのように意味をなさないかわかりません。手続き型言語(イベントプログラミングは1つ)で制御を放棄することについてはすでに多くの説明があり、純粋に関数型の言語は高階関数を持っているため、Inversion of Controlのような概念を必要としません。
また、記事では、Martin FowlerがIoCについて詳しく説明しています。
それで、IoCはもっぱらオブジェクト指向の概念であり、正確には何ですか?
IoCは、ほとんどのOO言語が課す制限の範囲内で関数をデータに変換し、それらの関数としての関数を引数として他の関数に渡そうとします。 IoCの一部だけではありませんが、その一部があります。
ファクトリデザインパターンもあります。このパターンでは、オブジェクトのツリーが構築および構成されてから渡されます。
私にとって、IoCは排他的にオブジェクト指向の概念です。
あなたの答えは?
解決
理論的な問題を実装の観点から見ます。最初に発生する質問は、正確にどのコントロールを反転しますかですか?
それから、オブジェクト、メソッド、関数、または他のものが渡されるかどうかは関係なく、実際にコードが何をするかがわかります。
要するに、依存性注入を行うと、(リソースの)依存性の作成と使用の制御が逆になります。
Windows API関数にコールバック関数へのポインターを与えると、独自のパラメーターを使用して関数を呼び出す制御を与えます。
おわかりのように、IoCは単なる理論上の概念であり、もちろん、さまざまな実用的な実装が可能です。
他のヒント
制御の反転は、間違いなくオブジェクト指向の概念ではありません。
IoCは存在し、OO以外の言語で非常に頻繁に使用されます。たとえば、Cでは非常に一般的です。この主な例はWindows APIです。コールバックを介して機能するWindows API関数を呼び出すときはいつでも、基本的には最も基本的な形でIoCを使用しています。
たとえば、 EnumWindows 関数を見てください。これを使用して、関数ポインター(EnumWindowsProc)をライブラリに渡し、ライブラリコード内からコードが実行されます。
これをウィキペディアの制御の反転の定義と比較してください。"制御の反転は、ライブラリプロシージャがユーザープロシージャを呼び出したときに発生します。
まったく同じです。
ただし、IoCは、OOPに付属する豊富な型システムと他の多くのツールを追加すると、実際に非常に強力で柔軟で使いやすくなります。これは、「より良い」ため、より一般的になります。動作しますが、OOPより前に存在していました。
まあ、「制御の反転」の概念;関数ポインタを渡す方法がある場合はどこでも適用できるようです。基本的に、プラグインの概念と互換性のある署名(たとえば、ドライバーのような)を持つDLLは、IoCの形式にすぎません。
ただし、IoCをリッチタイプおよびコンテナモデルで使用する場合、基本的にオブジェクト指向の世界に自動的に移動します。また、OOPの概念は、特に純粋仮想クラス(または「インターフェース」とも呼ばれる)で多重継承をサポートする言語では、IoCの概念に非常によく対応しています。
実際、IoCのOO実装は非常に精巧です。関数はファーストクラスの市民ではないことが多いためです。
Azderが述べたように、IoCは多くの理由で使用されます。納得させるためにここに要約します:)
反復
#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 );
一般的なイベントのディスパッチ
//javascript
document.getElementById( "mybutton" )
.addEventListener(
function(e){ alert("buttonPressed") } );
これらの例はいずれもオブジェクト指向、q.e.d。ではありません。