web-dev-qa-db-ja.com

アスペクト指向プログラミングとオブジェクト指向プログラミング

ここや世界中のほとんどの開発者と同様に、私は長年オブジェクト指向プログラミング(OOP)技術を使用してソフトウェアシステムを開発しています。したがって、アスペクト指向プログラミング(AOP)が従来のOOPでは完全にまたは直接解決できない問題の多くに対処していることを読んだとき、私は一時停止し、それが本当ですか?

このAOPパラダイムの鍵を学ぶために多くの情報を読みましたが、私は同じ場所にいるので、実世界のアプリケーション開発におけるその利点をよりよく理解したかったのです。

誰かが答えを持っていますか?

186
yeradis

なぜ「vs」なのですか? 「vs」ではありません。アスペクト指向プログラミングは、機能プログラミングと組み合わせて使用​​できますが、オブジェクト指向プログラミングと組み合わせて使用​​することもできます。 「vs」ではなく、「アスペクト指向プログラミングwithオブジェクト指向プログラミング」です。

私にとって、AOPはある種の「メタプログラミング」です。コードを追加するだけで、AOPなしでAOPを実行することもできます。 AOPを使用すると、このコードを書く手間が省けます。

ウィキペディアには、このメタプログラミングの最良の例の1つがあります。多くの「set ...()」メソッドを持つグラフィカルクラスがあるとします。各設定メソッドの後、グラフィックのデータが変更されたため、グラフィックが変更されたため、画面上でグラフィックを更新する必要があります。グラフィックを再描画するには、「Display.update()」を呼び出す必要があります。古典的なアプローチは、コードを追加することでこれを解決することです。各setメソッドの最後に記述します

void set...(...) {
    :
    :
    Display.update();
}

3つのsetメソッドがある場合、それは問題ではありません。 200(仮想)がある場合、これをどこにでも追加するのは本当につらいことです。また、新しいset-methodを追加するときは必ず、最後にこれを追加することを忘れないでください。そうしないと、バグが作成されます。

AOPは、大量のコードを追加せずにこれを解決し、代わりにアスペクトを追加します。

after() : set() {
   Display.update();
}

以上です!更新コードを自分で書く代わりに、set()ポイントカットに達した後、このコードを実行する必要があり、このコードを実行することをシステムに伝えるだけです。 200のメソッドを更新する必要はありません。新しいsetメソッドにこのコードを追加することを忘れないでください。さらに、ポイントカットが必要です:

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

どういう意味ですか?つまり、メソッドが返すもの(最初のアスタリスク)またはどのパラメーターを取るか(3番目のアスタリスク)andこれはMyGraphicsClassのメソッドであり、このクラスはパッケージ "com.company。*"の一部であり、これはset()ポイントカットです。そして、最初のコードは「afterset pointcutであるメソッドを実行した後、次のコードを実行します」と言っています。

AOPが問題をエレガントに解決する方法をご覧ください。実際、ここで説明するすべてのことはコンパイル時に実行できます。 AOPプリプロセッサは、クラス自体をコンパイルする前に、ソースを変更するだけです(たとえば、すべてのset-pointcutメソッドの最後にDisplay.update()を追加します)。

ただし、この例は、AOPの大きな欠点の1つも示しています。 AOPは実際、多くのプログラマーが「Anti-Pattern」と見なしていることを行っています。正確なパターンは「 Action at a distance 」と呼ばれます。

離れた場所でのアクションは、プログラムのある部分の動作が、プログラムの別の部分の操作を識別するのが困難または不可能であることに基づいて大きく変化するアンチパターン(認識される一般的なエラー)です。

プロジェクトの初心者として、set-methodのコードを読んで、表示が更新されないように見えるため、壊れていると考えるかもしれません。 set-methodのコードを見るだけではseeでありません。実行後、他のコードが「魔法のように」実行される表示を更新します。これは重大な欠点だと思います!メソッドを変更すると、奇妙なバグが発生する可能性があります。特定の事柄は正しく動作しているように見えても明らかではないコードのコードフローをさらに理解することは(私が言ったように、魔法のように...なんとかして)、本当に難しいです。

更新

それを明確にするために:AOPは悪いものであり、使用すべきではないという印象を持っている人がいるかもしれません。それは私が言っていることではありません! AOPは実際には素晴らしい機能です。 「丁寧に使って」と言うだけです。 AOPは、同じAspectに対して通常のコードとAOPを混同した場合にのみ問題を引き起こします。上記の例では、グラフィカルオブジェクトの値を更新し、更新されたオブジェクトをペイントするアスペクトがあります。それは実際には単一の側面です。その半分を通常のコードとしてコーディングし、残りの半分をアスペクトとしてコーディングすることが問題を追加します。

AOPを完全に異なる側面に使用している場合、例えばロギングの場合、アンチパターンの問題は発生しません。その場合、プロジェクトの初心者は「これらのログメッセージはどこから来るのでしょうか。コードにログ出力が表示されません」と思うかもしれませんが、それは大きな問題ではありません。彼がプログラムロジックに加えた変更は、ログ機能をほとんど壊しません。また、ログ機能に加えた変更は、プログラムロジックをほとんど壊しません。これらの側面は完全に分離されています。 AOPをログに使用することには、プログラムコードが何をすべきかに完全に集中できるという利点があり、コードが至る所にある何百ものログメッセージで乱雑になることなく、洗練されたログを保持できます。また、新しいコードが導入されると、適切なコンテンツとともに適切なタイミングで魔法のようなログメッセージが表示されます。初心者プログラマーは、なぜ彼らがそこにいるのか、どこから来たのか理解できないかもしれませんが、「正しいこと」を「適切なタイミング」で記録するため、彼らがそこにいるという事実を喜んで受け入れて、他の何かに進むことができます。

したがって、私の例でのAOPの適切な使用法は、setメソッドを介して値が更新された場合に常にログを記録することです。これはアンチパターンを作成せず、問題の原因になることはほとんどありません。

AOPを簡単に悪用して非常に多くの問題を作成できる場合、すべてを使用するのは悪い考えです。しかし、どのテクノロジーを悪用することはできませんか?データのカプセル化を悪用したり、継承を悪用したりできます。ほとんどすべての有用なプログラミング技術が悪用される可能性があります。悪用できない機能のみを含むように制限されたプログラミング言語を考えてください。機能が最初に使用されることを意図されていたときにのみ使用できる言語。このような言語は非常に制限されているため、実世界のプログラミングに使用できる場合でも議論の余地があります。

302
Mecki

OOPとAOPは相互に排他的ではありません。 AOPはOOPに追加するのに適しています。 AOPは、メソッドコードをこの標準コードで詰まらせることなく、ロギング、パフォーマンストラッキングなどの標準コードをメソッドに追加するのに特に便利です。

27
norbertB

アスペクト指向のプログラミングは、ロギング、セキュリティなどの分野横断的な懸念を実装する素晴らしい方法を提供します。これらの分野横断的な懸念は、多くの場所に適用する必要があるが、実際にはビジネスロジックとは何の関係もないロジックの一部です。

AOPをOOPの代替としてではなく、ニースのアドオンとして、コードをよりクリーンにし、疎結合にし、ビジネスロジックに焦点を当てる必要はありません。 AOPを適用することにより、2つの大きなメリットが得られます。

  1. コードベース全体に散在しているのではなく、各懸念事項のロジックが1つの場所にあります。

  2. クラスは主な関心事(またはコア機能)のコードのみを含み、副次的な関心事はアスペクトに移動されているため、クラスはよりクリーンです。

27
nkr1pt

この質問に対する一般的な答えはないと思いますが、注意すべきことの1つは、AOPはreplaceOOP =ただし、支配的な構成のいわゆる専制に対処する特定の分解機能を追加します(- 1 )(または横断的関心事) 。

特定のプロジェクトで使用するツールと言語を制御している限り、特定のケースで確実に役立ちますが、アスペクトの相互作用や [〜#〜] ajdt [〜#〜] プログラムを理解するために。

Gregor Kiczalesは、Google Tech TalksでAOPに関する興味深い入門講演を行ったことがありますが、これを視聴することをお勧めします。 アスペクト指向プログラミング:モジュール方式のラジカル研究

10
fhe

まず、AOPはOOPに置き換わるものではありません。 AOPはOOPを拡張します。 OOPのアイデアと実践は関連性を維持します。適切なオブジェクト設計があれば、アスペクトで拡張するのが簡単になるでしょう。

AOPがもたらすアイデアは重要だと思います。クラス自体を変更することなく、プログラムのさまざまなクラスに横断的な関心事を実装する方法を考え出す必要があります。しかし、AOPは最終的には、私たちが使用する他のツールの一部になり、別個のツールや手法ではなくなると思います。これはすでに起こっています。

RubyおよびPythonのようないくつかの動的言語には、同じ問題を解決するmixinのような言語構造があります。これはAOPによく似ていますが、言語。

SpringとCastleおよび他のいくつかの依存性注入フレームワークには、注入するクラスに動作を追加するオプションがあります。これはランタイムウィービングの方法であり、これには多くの可能性があると思います。

AOPを使用するためにまったく新しいパラダイムを学ぶ必要はないと思います。アイデアは興味深いものですが、既存のツールや言語に徐々に吸収されています。情報を入手して、これらのツールを試してみてください。

8
Mendelt

私はこの質問に答えるのに遅れていますが、それは私のお気に入りのトピックなので、私の意見を共有させてください。

[〜#〜] oop [〜#〜]は、主に組織を整理するために使用されますビジネスロジック while [〜#〜] aop [〜#〜]整理するのに役立ちます非機能的なもの監査、ロギング、トランザクション管理、セキュリティなど

このようにして、ビジネスロジックを、コードを簡潔にするノンフィクションロジックと切り離すことができます。

他の利点は、インターフェイスを実装せずにアドバイス(監査の例)を非常に一貫して適用できることです。これにより、ビジネスロジックに触れることなく変更を柔軟に行うことができます。

1
Gaurang Popat

AOPは、この概念を扱う新しいプログラミングパラダイムです。アスペクトは、アプリケーションの特定の非機能部分を実装するソフトウェアエンティティです。

この記事はアスペクト指向プログラミングから始めるのに良い場所だと思います: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/

1
JafTalks