Webフレームワークを開発するためにSpringフレームワークを使用する主な利点として、「依存性注入」と「制御の反転」がよく言及されています。
可能であれば、例を使用して非常に簡単な言葉でそれを説明できますか?
たとえば:オブジェクトEmployee
があり、オブジェクトAddress
に依存しているとします。オブジェクトEmployee
への依存関係を定義するAddress
に対応するBeanを定義します。
SpringがEmployee
オブジェクトを作成しようとすると、Employee
がAddress
に依存していることがわかるため、最初にAddress
オブジェクト(依存オブジェクト)を作成し、次にEmployee
オブジェクトに挿入します。
制御の反転(IOC)および依存性注入(DI)は同じ意味で使用されます。 IOCはDIを介して実現されます。 DIは依存関係を提供するプロセスであり、IOCはDIの最終結果です。 (注:DIがIOCを達成する唯一の方法ではありません。 他の方法 もあります。)
DIにより、オブジェクトを作成する責任はアプリケーションコードからSpringコンテナに移ります。この現象はIOCと呼ばれます。
この2つの用語の簡単な理解を書き留めておきます:
For quick understanding just read examples*
依存性注入(DI):
一般的に、依存性注入とは、メソッドに依存オブジェクトを作成させるのではなく、メソッドにパラメータとして依存オブジェクトを渡すを意味します。
実際に意味するのは、メソッドが特定の実装に直接依存しないことです。要件を満たす実装はすべてパラメーターとして渡すことができます。
このオブジェクトの実装により、依存関係が定義されます。そして、春はそれを利用可能にします。
これにより、疎結合のアプリケーション開発が行われます。
Quick Example:EMPLOYEE OBJECT WHEN CREATED,IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object)*.<br>
Inversion of Control(IoC)Container:
これはフレームワークの一般的な特性です。IOC manage Java objects
– BeanFactoryによるインスタンス化から破壊まで。
-IoCコンテナーによってインスタンス化されるJavaコンポーネントはBeanと呼ばれ、IoCコンテナーはBeanのスコープ、ライフサイクルイベント、およびAOP機能を管理します 。
QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it
。
制御の反転を実装することにより、ソフトウェア/オブジェクトの消費者は、制御またはオプションが少なくなるのではなく、ソフトウェア/オブジェクトに対してより多くの制御/オプションを取得します。
設計ガイドラインとしての制御の反転は、次の目的に役立ちます。
特定のタスクの実行と実装の分離があります。
すべてのモジュールは、その目的に焦点を当てることができます。
モジュールは、他のシステムが何を行うかについては想定していませんが、契約に依存しています。
モジュールを交換しても、他のモジュールに副作用はありません
ここでは物事を要約します。トピックの詳細を理解するには、次のリンクをご覧ください。
例とともに読むとよい
制御の反転(IOC):
IoCは、システム内の制御フローの反転を記述する設計パターンであるため、実行フローは中央のコードによって制御されません。これは、コンポーネントが他のコンポーネントの抽象化にのみ依存し、依存オブジェクトの作成を処理する責任を負わないことを意味します。代わりに、オブジェクトインスタンスは、依存性注入(DI)を介してIoCコンテナーによって実行時に提供されます。
IoCは、ソフトウェアコンポーネントの再利用、疎結合、および簡単なテストを容易にする優れたソフトウェア設計を可能にします。
依存性注入(DI):
DIは、依存関係をオブジェクトのコンストラクターに渡す手法です。オブジェクトがコンテナからロードされている場合、その依存関係はコンテナによって自動的に提供されます。これにより、手動でインスタンスを作成しなくても依存関係を利用できます。これにより、結合が減少し、オブジェクトインスタンスの存続期間をより細かく制御できます。
Springでは、オブジェクトは疎結合されています。つまり、各クラスは互いに独立しているため、すべてを個別にテストできます。しかし、これらのクラスを使用する場合、クラスは最初にインスタンス化する必要がある他のクラスに依存する場合があります。
したがって、クラスAがクラスBに依存していることをSpringに伝えます。したがって、クラスAのBean(クラスのような)を作成するとき、クラスAの前にクラスBをインスタンス化し、セッターまたはコンストラクターDIメソッドを使用してクラスAにそれを注入します。つまり、実行時に依存関係をspringに伝えています。これはDIです。
オブジェクト(Bean)を作成し、それらとその集合をハードコーディングする代わりにSpringに保持する責任を割り当てているため、Inversion Of Control(IOC)と呼びます。
Spring:Springは、Java Platformの「制御の反転」コンテナです。
Inversion of Control(IoC):Inversion of Control(IoC)はオブジェクト指向プログラミングの手法であり、オブジェクト結合は実行時に「アセンブラ」オブジェクトによって制限され、通常、静的分析を使用したコンパイル時にはわかりません。
依存性注入(DI):「依存性注入は、ハードコードされた依存性を削除し、実行時またはコンパイル時に依存性を変更できるソフトウェア設計パターンです。」 -wiki。
制御の反転-Spring IOCコンテナーにSpring Beanを作成およびインスタンス化する制御を与えることを意味し、開発者が行う唯一の作業は、Spring xmlファイルでBeanを構成することです。
依存性注入
クラスの従業員を考えます
class Employee {
private int id;
private String name;
private Address address;
Employee() {
id = 10;
name="name";
address = new Address();
}
}
クラスAddressを検討します
class Address {
private String street;
private String city;
Address() {
street="test";
city="test1";
}
}
上記のコードでは、住所クラスの値は、従業員クラスがインスタンス化されるときにのみ設定されます。これは、住所クラスと従業員クラスの依存関係です。また、Springは、この依存関係を注入する2つの方法を提供することにより、依存関係注入の概念を使用してこの問題を解決します。
Addressクラスの参照を取るEmployeeクラスのセッターメソッド
public void setAddress(Address addr) {
this.address = addr;
}
Addressを受け入れるEmployeeクラスのコンストラクター
Employee(Address addr) {
this.address = addr;
}
このようにして、セッター/コンストラクターインジェクションを使用して、Addressクラスの値を個別に設定できます。
Inversion of Controlは、保守しやすい再利用可能なモジュール式ソフトウェアフレームワークの作成を支援するソフトウェアアーキテクチャの一般的な設計原則です。
これは、一般的なライブラリまたは再利用可能なコードから制御の流れを「受け取る」設計原則です。
それをよりよく理解するために、コーディングの初期の時代にどのようにコーディングしていたかを見てみましょう。手続き型/従来型の言語では、ビジネスロジックが一般にアプリケーションのフローを制御し、汎用または再利用可能なコード/関数を「呼び出し」ます。たとえば、単純なコンソールアプリケーションでは、制御の流れはプログラムの命令によって制御されます。これには、いくつかの一般的な再利用可能な関数の呼び出しが含まれる場合があります。
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要素を作成するためのフレームワークが既に利用可能です。アプリケーションのビジネスロジックを記述するとき、フレームワークのイベントは、ビジネスロジックコード(イベントが発生したとき)を呼び出し、その逆ではありません。
フレームワークのコードは私のビジネスロジックを認識していませんが、コードを呼び出す方法はまだわかります。これは、イベント/デリゲート、コールバックなどを使用して実現されます。ここでは、フローの制御は「反転」されています。
そのため、静的にバインドされたオブジェクトの制御フローに依存する代わりに、フローはオブジェクトグラフ全体と異なるオブジェクト間の関係に依存します。
依存性注入は、オブジェクトの依存性を解決するためのIoC原則を実装する設計パターンです。
簡単に言えば、コードを記述しようとすると、異なるクラスを作成して使用することになります。 1つのクラス(クラスA)は他のクラス(クラスBおよび/またはD)を使用できます。したがって、クラスBとDはクラスAの依存関係です。
単純な例えは、クラスカーです。車は、エンジン、タイヤなど、他のクラスに依存する場合があります。
依存性注入では、依存クラス(ここではクラスカー)がその依存性(クラスエンジンおよびクラス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人のユーザーがエディターでフランス語を書き始める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型の具体的なインスタンスを受け取る必要があります。
これで、コンストラクター、パブリックプロパティ、またはメソッドに依存関係を注入できます。
Constructor DIを使用してクラスを変更してみましょう。変更されたTextEditorクラスは次のようになります。
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
呼び出し元のコードは、テキストエディターの作成中に、適切なSpellCheckerタイプをTextEditorのインスタンスに挿入できるようにします。
完全な記事を読むことができます こちら
Employeeで住所インスタンスを取得する従来の方法は、Addressクラスの新しいインスタンスを作成することです。Springは、すべての依存オブジェクトを作成します。したがって、オブジェクトについて心配する必要はありません。
そのため、Springでは、依存関係オブジェクトを提供するスプリングコンテナに依存しています。
IOCは、他の誰かにオブジェクトを作成させる技術です。そして、春の場合の他の誰かはIOCコンテナです。
依存性注入は、あるオブジェクトが別のオブジェクトの依存性を提供する手法です。