web-dev-qa-db-ja.com

シンプルな英語のAOP、依存性注入、制御の逆転とは

AOP、依存性注入、および制御の反転SPRING関連の概念を理解しようとしましたが、理解に苦労しています。

誰でも簡単な英語でこれを説明できますか?

34
Rachel

あなたの混乱を理解し、これらの概念がどのように関連しているかを理解するのに少し時間がかかりました。だからここにこれすべての私の(どういうわけか個人的な)説明があります:

1。制御の反転

制御の反転 は、実際に実行されたときからの動作の仕様の分離を指す、かなり一般的な設計原則です。たとえば、

myDependency.doThis();

myDependency.onEventX += doThis();

後者では、より柔軟な直接呼び出しがありません。一般的な形式では、制御の反転はobserver patternevents、またはcallbacks

2。依存関係の逆転

依存関係の逆転は、もう1つの設計原則です。大まかに言えば、高レベルの抽象化は低レベルの抽象化に直接依存すべきではないと述べています。これは実際に、より高いレベルの抽象化がより低いレベルの抽象化なしでは再利用できない設計をもたらします。

 class MyHighLevelClass {
     MyLowLevelClass dep = new MyLowLeverClass();
 }

 class App {
     void main() {  new HighLevelClass().doStuff(); }
 }

ここで、MyHighLevelClassは、MyLowLevelClassにアクセスしないとコンパイルできません。このカップリングを解除するには、インターフェースを持つ低レベルクラスをabstractし、直接のインスタンス化を削除する必要があります。

class MyLowLevelClass implements MyUsefulAbstraction { ... }

class MyHighLevelClass {

    MyUsefulAbstraction dep;

    MyHighLevelClass( MyUsefulAbstraction dep ) {
        this.dep = dep;
    }
}

class App {
     void main() {  new HighLevelClass( new LowLevelClass() ).doStuff(); }
 }

原則として、依存関係の反転を強制するためにコンテナのような特別なものは必要ないことに注意してください。良い読みは、ボブおじさんによる 依存関係の逆転の原則 です。

3。依存性注入

ここで、依存性注入が行われます。私に dependency injection = IoC + dependency inversion

  1. 依存関係は外部から提供されるため、依存関係の逆転の原則を適用します
  2. コンテナは依存関係を設定します(私たちではありません)ので、制御の反転について話します

上記で提供した例では、コンテナーを使用してオブジェクトをインスタンス化し、コンストラクターに依存関係を自動的にinject注入する場合、依存関係の注入を実行できます(次に、DIコンテナーについて頻繁に説明します)。

 class App {
     void main() {  DI.getHighLevelObject().doStuff(); }
 }

さまざまな 注入の形式 があることに注意してください。また、この観点では、 セッター注入 はコールバックの形式と見なすことができます。DIコンテナーはオブジェクトを作成し、セッターをコールバックします。制御の流れは事実上逆になります。

4。 AOP

厳密に言えば、AOPは前の3つのポイントとはほとんど関係がありません。 AOPに関する主要な論文 は非常に一般的であり、さまざまなソースを(異なる言語で表現される可能性がある)一緒に織り込み、実用的なソフトウェアを作成するというアイデアを提示します。

AOPについてはこれ以上詳しく説明しません。ここで重要なのは、依存関係の注入とAOPが効果的にうまく連携して、製織が非常に簡単になるということです。 IoCコンテナーと依存関係の注入を使用してオブジェクトのインスタンス化を抽象化する場合、IoCコンテナーを使用して、依存関係を注入する前にアスペクトを簡単に織り込むことができます。それ以外の場合は、特別なコンパイルまたは特別なClassLoaderが必要になります。

お役に立てれば。

47
ewernli

依存関係の注入は、非常によく説明されています 依存関係の注入を5歳の人に説明する方法は?

冷蔵庫から出て自分で物を取り出すと、問題が発生する可能性があります。ドアを開けたままにしておくと、ママやパパが欲しくないものを手に入れるかもしれません。私たちが持っていないものや期限切れのものを探しているかもしれません。

あなたがしなければならないことは、「昼食と一緒に飲むものが必要です」という必要性を述べることです。それから、あなたが座って食べるときにあなたが何かを持っていることを確認します。

AOP-アスペクト指向プログラミング-基本的に、ELSEWHEREにあるルールに基づいて、作成したソースが他のコードで変更されることを意味します。これは、たとえば「すべてのメソッドの最初の行として、 'log.debug( "enteringmethod()")'を中央の場所に置き、 「アスペクト」とは、最初のソース行から最後の行まで以外の方法でコードを検索することの名前です。

制御の反転とは、基本的にはすべてを制御する中心的なコード(main()の巨大なスイッチなど)ではなく、「なんとかして」呼び出されるコードの断片がたくさんあることを意味します。主題はウィキペディアで議論されています: http://en.wikipedia.org/wiki/Inversion_of_control

aOPについて少しお話ししましょう。理解しやすくなることを願っています。 AOPの基本原則は、コードの多くの場所に戻り、コードのビジネスに属さない一般的なタスク/アスペクトを見つけることです。たとえば、関数へのすべての入り口にログオンするために書き込むか、オブジェクトが作成されたときにそれをラップするか、特定の関数を呼び出すときに管理者に電子メールを送信します。そのため、プログラマーがこれらの非ビジネス面を処理する代わりに、私たちはそれを取り上げ、シーンに基づいてこれらの面を管理します。 AOPの1つのレッグでのすべての基本...

1
Ziv.Ti

依存性注入と制御の反転の違いについては、

http://martinfowler.com/articles/dipInTheWild.html

(「依存関係の逆転を意味しますか?」セクション)

サマリー:

DIは、1つのオブジェクトが依存関係を取得する方法についてです。依存関係が外部から提供されている場合、システムはDIを使用しています。

IoCは、だれが通話を開始するかについてです。コードが呼び出しを開始する場合、それはIoCではありません。コンテナー/システム/ライブラリーが提供したコードにコールバックする場合、それはIoCです。

1
Maxim Eliseev

これら3つはすべて異なる概念ですが、すべて連携して機能するため、Springアプリは多くの場合、それらすべてを一度に利用します。例を挙げましょう。

さまざまなことを実行できるWebアプリケーションがあるとします。このアプリケーションはさまざまな方法で構築できますが、1つの方法は、これらのそれぞれの処理を担当するクラスを作成することです。これらのクラスをどこかから呼び出して作成する必要があります。 1つのオプションは、これらの各サービスの1つを作成し、ソケットを開き、これらのサービスが呼び出されたときにそれらのサービスへの呼び出しを渡す大きなメインクラスを用意することです。残念ながら、私たちは自分自身でgodクラスを作成しました。ロジックが多すぎて、プログラムのすべてがどのように機能するかについてあまりにも多くを知っています。プログラムについて何かを変更した場合、おそらくこのクラスを変更する必要があります。

また、テストするのが難しいです。他のクラスを直接インスタンス化して呼び出す場合、クラスを個別にテストすることはできません。単体テストは、書き方がはるかに難しくなります。

これを回避する方法は、制御の反転を使用することです。 「大丈夫、これらはサービスクラスです。誰がそれらを初期化しますか?私ではありません。」通常、それぞれがLoginServiceやBillingServiceなどのインターフェースを定義します。そのインターフェースの実装は複数あるかもしれませんが、アプリは気にしません。特定の種類のサービスまたは特定の名前のサービスを要求できることを知っているだけで、何かいい結果が返されます。

依存性注入により、litleのすべての部分を一緒に配線できます。クラスには、アクセス可能なフィールド、コンストラクター引数、またはアクセスする必要がある他のコンポーネントへの参照であるセッターメソッドがあります。これにより、単体テストがはるかに簡単になります。テスト対象のオブジェクトを作成し、モックまたはスタブの依存関係をスローして、オブジェクトが単独で正しく動作することをテストできます。

さて、私たちの実際のアプリケーションは、すべてが同じように一緒に配線される必要のある複雑な雑片です。これを実現するには、アプリケーションが推測できるようにする方法(「このクラスはUserServiceを必要とし、UserServiceを実装しているクラスが1つだけある」を含む)や、XMLでどのように接続するかを注意深く説明するなど、多くの方法があります。またはJava。 Springは、その中心にある、これらのクラスを相互に接続する処理を行うサービスです。

次に、AOPに進みます。精巧な方法で相互に関連付けられているこれらのクラスがすべてあるとしましょう。非常に一般的な方法で説明したい分野横断的な懸念がいくつかあります。たとえば、サービスが呼び出されるたびにデータベーストランザクションを開始し、サービスが例外をスローしない限り、そのトランザクションをコミットしたいとします。 Springは、そのようなタスクを実行するためのユニークな立場にあることがわかりました。 Springは、クラスが必要とするインターフェースを実装するプロキシクラスをその場で作成し、クラスをプロキシにラップすることができます。現在、アスペクト指向プログラミングを実行するためにIoCと依存関係の注入は必ずしも必要ではありませんが、それを実現するには非常に便利な方法です。

1

Spring in Actionの簡単な比較:

DIはアプリケーションオブジェクトを互いに分離するのに役立ちますが、AOPは、影響を与えるオブジェクトから分野横断的な関心事を分離するのに役立ちます。

1
TastyCode