ソフトウェア エンジニアリングにおいて、制御の反転( IoC ) とは、コンピュータ プログラムのカスタム記述部分が外部ソース (フレームワークなど) から制御フローを受け取る設計原理のことです。「反転」という用語は歴史的なものです。この設計のソフトウェア アーキテクチャは、手続き型プログラミングと比較して制御を「反転」します。手続き型プログラミングでは、プログラムのカスタム コードが再利用可能なライブラリを呼び出して汎用タスクを処理しますが、制御の反転では、カスタム コードを呼び出しているのは外部ソースまたはフレームワークです。
制御の反転は、GUI環境の台頭以来、アプリケーション開発フレームワークで広く使用されており[1] [2] 、GUI環境とWebサーバーアプリケーションフレームワークの両方で使用され続けています。制御の反転により、アプリケーションプログラマが定義したメソッドによってフレームワークを拡張できるようになります。 [3]
イベント駆動型プログラミングは、多くの場合、IoC を使用して実装されるため、カスタム コードはイベントの処理のみに関心を持つ必要があり、イベント ループとイベント/メッセージのディスパッチはフレームワークまたはランタイム環境によって処理されます。Web サーバー アプリケーション フレームワークでは、ディスパッチは通常ルーティングと呼ばれ、ハンドラーはエンドポイントと呼ばれることがあります。
別の意味
「制御の反転」という語句は、Javaプログラマーのコミュニティでは、SpringフレームワークなどのJavaフレームワークの「IoCコンテナ」で発生する依存性注入(オブジェクトに必要なサービスを渡す)のパターンを指すためにも別途使用されるようになりました。[4]この異なる意味での「制御の反転」は、フレームワークに制御フロー(コールバックなどのアプリケーションコードの実行時間に対する制御)を許可するという本来の意味ではなく、アプリケーションオブジェクトによって使用される依存関係の実装に対するフレームワークの制御を許可することを指します[ 5]。
概要
たとえば、従来のプログラミングでは、アプリケーションのメイン関数はメニューライブラリに関数呼び出しを行い、利用可能なコマンドのリストを表示し、ユーザーにその1つを選択するよう問い合わせる場合があります。[6]ライブラリは選択されたオプションを関数呼び出しの値として返し、メイン関数はこの値を使用して関連付けられたコマンドを実行します。このスタイルは、テキストベースのインターフェイスでは一般的でした。たとえば、電子メールクライアントは、新しいメールを読み込む、現在のメールに返信する、新しいメールを作成するなどのコマンドを含む画面を表示する場合があり、ユーザーがキーを押してコマンドを選択するまでプログラムの実行はブロックされます。
一方、制御の反転では、ウィンドウ システム、メニュー、マウスの制御など、共通の動作要素とグラフィック要素を認識するソフトウェア フレームワークを使用してプログラムが記述されます。カスタム コードは、メニュー項目のテーブルを提供したり、各項目のコード サブルーチンを登録したりするなど、フレームワークの「空白を埋める」役割を果たしますが、ユーザーの操作を監視し、メニュー項目が選択されたときにサブルーチンを呼び出すのはフレームワークです。メール クライアントの例では、フレームワークはキーボードとマウスの両方の入力を追跡し、いずれかの方法でユーザーが呼び出したコマンドを呼び出すと同時に、ネットワーク インターフェイスを監視して新しいメッセージが到着したかどうかを調べ、ネットワーク アクティビティが検出されたときに画面を更新できます。同じフレームワークを、スプレッドシート プログラムやテキスト エディターのスケルトンとして使用できます。逆に、フレームワークは Web ブラウザー、スプレッドシート、またはテキスト エディターについて何も認識しません。これらの機能を実装するには、カスタム コードが必要です。
制御の反転は、再利用可能なコードと問題固有のコードがアプリケーション内で一緒に動作するにもかかわらず、独立して開発されるという強い意味合いを持ちます。コールバック、スケジューラ、イベントループ、テンプレートメソッドは、制御の反転の原則に従う設計パターンの例ですが、この用語はオブジェクト指向プログラミングのコンテキストで最も一般的に使用されます。(依存性注入は、Javaフレームワークによって普及した「依存性の実装に対する制御を反転する」という別の特定のアイデアの例です。)[4]
制御の反転は、「ハリウッド原則:私たちに電話しないでください、私たちから電話します」と呼ばれることもあります。[1]
背景
制御の反転はコンピュータサイエンスでは新しい用語ではありません。マーティン・ファウラーは、このフレーズの語源を 1988 年にまで遡っていますが[7] 、これは1970 年代にマイケル・ジャクソンがジャクソン構造化プログラミング手法で説明したプログラム反転の概念と密接に関連しています[8] 。ボトムアップ パーサーはトップダウン パーサーの反転と見なすことができます。つまり、1 つのケースでは制御はパーサーにあり、もう 1 つのケースでは制御は受信アプリケーションにあります。
この用語は、マイケル・マットソンが論文で使用したもの(本来の意味はフレームワークがアプリケーションコードを呼び出すことであり、その逆ではない)[9]で、その後ステファノ・マッツォッキがそこから採用し[10]、1999年に廃止されたApache Software FoundationプロジェクトであるAvalonで普及させました。このプロジェクトでは、実行フローを制御するだけでなく、親オブジェクトが子オブジェクトの依存関係を渡すことも指していました。[11]このフレーズは、2004年にロバート・C・マーティンとマーティン・ファウラーによってさらに普及しました。後者は、この用語の起源を1980年代にさかのぼります。[7]
説明
従来のプログラミングでは、ビジネス ロジックのフローは、互いに静的にバインドされたオブジェクトによって決定されます。制御の反転では、フローはプログラム実行中に構築されるオブジェクト グラフに依存します。このような動的なフローは、抽象化によって定義されるオブジェクトの相互作用によって可能になります。この実行時のバインドは、依存性注入やサービス ロケーターなどのメカニズムによって実現されます。IoC では、コンパイル中にコードを静的にリンクすることもできますが、実行するコードを見つけるには、コード自体の直接参照ではなく、 外部構成からその説明を読み取ります。
依存性注入では、依存オブジェクトまたはモジュールは、実行時に必要なオブジェクトに結合されます。プログラム実行中にどの特定のオブジェクトが依存性を満たすかは、通常、静的分析を使用してコンパイル時に知ることはできません。ここではオブジェクトの相互作用の観点から説明していますが、この原則は、オブジェクト指向プログラミング以外のプログラミング方法論にも適用できます。
実行中のプログラムがオブジェクトを相互にバインドするには、オブジェクトが互換性のあるインターフェースを持っている必要があります。たとえば、クラスは、クラスによって実装されているAインターフェースに動作を委任する場合があります。プログラムは、およびをインスタンス化してから、に挿入します。
IBABBA
使用
- XDE用Mesaプログラミング環境、1985年[1]
- Visual Basic (クラシック)、1991 年。
- HTML DOM イベント
- スプリングフレームワーク[5]
- ASP.NETコア[12]
- テンプレートメソッドパターン
サンプルコード
HTML DOM イベント
Web ブラウザは、HTML 内の DOM イベントに対する制御の反転を実装します。アプリケーション開発者は、これを使用してdocument.addEventListener()コールバックを登録します。
<!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > DOM レベル 2 </ title >
</ head >
< body >
< h1 > DOM レベル 2 イベント ハンドラー</ h1 >
< p >< large >< span id = "output" ></ span ></ large ></ p >
< script >
var registeredListener = function () { document . getElementById ( "output" ). innerHTML = "<large>登録されたリスナーが呼び出されました。</large>" ; } document . addEventListener ( "click" , registeredListener , true );
document . getElementById ( "output" ). innerHTML = "<large>イベント ハンドラーが登録されました。ページをクリックすると、Web ブラウザーがイベント ハンドラーを呼び出します。</large>"
</スクリプト>
</ボディ>
</ html >
Web アプリケーション フレームワーク
このASP.NET Core Webアプリケーションのサンプルコードは、Webアプリケーションホストを作成し、エンドポイントを登録し、フレームワークに制御を渡します。[12]
var builder = WebApplication.CreateBuilder ( args ); var app = builder.Build ( ) ; app.MapGet ( " /" , ( ) => "Hello World! " ) ; app.Run ( ) ;
参照
参考文献
- ^ abc Sweet, Richard (1985年6月25日). 「Mesaプログラミング環境」. ACM SIGPLAN Notices . 20 (7): 216–229. doi :10.1145/17919.806843.
- ^ Visual_Basic_(クラシック)
- ^ Johnson, Ralph E.; Foote, Brian (1988年6月~ 7月) 。「再利用可能なクラスの設計」。オブジェクト指向プログラミングジャーナル。1 (2):22~35。CiteSeerX 10.1.1.101.8594 。 2014年4月29日閲覧。
- ^ ab Fowler, Martin. 「Inversion of Control Containers and the Dependency Injection pattern」。MartinFowler.com 。2023年6月4日閲覧。
- ^ ab 「Spring Framework IoC コンテナー」。docs.spring.io 。2023年5 月 25 日閲覧。
- ^ 依存性注入。
- ^ ab マーティン・ファウラーのブリキにおける制御の反転
- ^ 「ジャクソン設計法入門」(PDF)。
- ^ Mattsson , Michael (1996 年 2 月)。「オブジェクト指向フレームワーク、方法論的問題に関する調査」。ルンド大学コンピュータサイエンス学部。CiteSeerX 10.1.1.36.1424。LU -CS-TR: 96-167。
- ^ Stefano Mazzocchi (2004年1月22日). 「On Inversion of Control」. 2004年2月2日時点のオリジナルよりアーカイブ。
- ^ 「IOC パターン - Avalon フレームワーク」。Apache Avalon プロジェクト。2023年6 月 8 日閲覧。
- ^ ab Ryan Nowak、Kirk Larkin、Rick Anderson。「ASP.Net Core でのルーティング」。learn.microsoft.com。microsoft。2023年5月 25 日取得。ルーティングは、
受信した HTTP 要求を照合し、それらの要求をアプリの実行可能エンドポイントにディスパッチする役割を担います。エンドポイントは、アプリの実行可能要求処理コードの単位です。エンドポイントはアプリで定義され、アプリの起動時に構成されます。
{{cite web}}: CS1 maint: 複数の名前: 著者リスト (リンク)
外部リンク
- 制御の反転の説明と実装例
- 制御の反転
