218

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

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

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

4

7 に答える 7

351

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

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

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

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

set-method が 3 つあれば問題ありません。200 (仮想) がある場合、これをどこにでも追加するのは本当に面倒です。また、新しい set-method を追加するときはいつでも、これを最後に追加することを忘れないようにする必要があります。そうしないと、バグが発生するだけです。

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

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

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

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

どういう意味ですか?つまり、メソッドが何を返すか (最初のアスタリスク) や受け取るパラメーター (3 番目のアスタリスク) に関係なく、メソッドの名前が "set*" (* は set の後に任意の名前が続く可能性があることを意味します)であり、それが MyGraphicsClass のメソッドでありこのclass がパッケージ "com.company.*" の一部である場合、これは set() ポイントカットです。そして、最初のコードは、「ポイントカットが設定されているメソッドを実行した後、次のコードを実行する」ことを示しています

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

ただし、この例は、AOP の大きな欠点の 1 つも示しています。AOP は、多くのプログラマーが「アンチパターン」と見なすことを実際に行っています。正確なパターンは「遠距離での行動」と呼ばれます。

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

プロジェクトの初心者として、表示を更新しないように見えるので、set-method のコードを読んで壊れていると考えるかもしれません。set-method のコードを見ただけでは、それが実行された後、表示を更新するために他のコードが「魔法のように」実行されることはわかりません。これは重大な欠点だと思います!メソッドに変更を加えることで、奇妙なバグが導入される可能性があります。特定のことが正しく機能しているように見えても、明らかではないコードのコード フローをさらに理解することは、非常に困難です。

アップデート

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

ロギングなど、まったく別の側面で AOP を使用する場合、アンチパターンの問題に遭遇することはありません。その場合、プロジェクトの初心者は「これらすべてのログ メッセージはどこから来るのか? コードにログ出力が表示されない」と疑問に思うかもしれませんが、それは大きな問題ではありません。プログラム ロジックに変更を加えてもログ機能が壊れることはほとんどなく、ログ機能に加えられた変更によってプログラム ロジックが壊れることはほとんどありません。これらの側面は完全に分離されています。ロギングに AOP を使用すると、コードが何百ものログ メッセージで散らかることなく、プログラム コードが本来の処理に完全に集中でき、洗練されたロギングを行うことができるという利点があります。また、新しいコードが導入されると、魔法のように適切なタイミングで適切な内容のログ メッセージが表示されます。

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

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

于 2008-10-24T09:21:17.003 に答える
35

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

AOPをOOPの代わりと見なすべきではありませんが、コードをよりクリーンで、ゆるく結合し、ビジネスロジックに集中させる優れたアドオンと見なす必要があります。

したがって、AOPを適用すると、次の2つの大きなメリットが得られます。

  1. 各懸念事項のロジックは、コードベース全体に散在しているのではなく、1か所にまとめられています。

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

于 2008-10-24T09:11:28.143 に答える
29

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

于 2008-10-24T09:09:24.170 に答える
11

この質問に対する一般的な答えはないと思いますが、注意すべきことの 1 つは、AOP はOOPに取って代わるものではなく、支配的な構成( 1 ) (または分野横断的な懸念)のいわゆる暴政に対処する特定の分解機能を追加することです。

特定のプロジェクトに使用するツールと言語を制御している限り、特定のケースでは確かに役立ちますが、側面の相互作用に関する新しいレベルの複雑さを追加し、AJDTなどの追加ツールを理解する必要もあります。あなたのプログラム。

Gregor Kiczales は、Google Tech Talks で AOP に関する興味深い紹介講演を行ったことがあるので、こちらをご覧になることをお勧めします: Aspect Oriented Programming: Radical Research in Modularity

于 2008-10-24T09:16:29.197 に答える
8

まず第一に、AOP は OOP に取って代わるものではありません。AOP は OOP を拡張します。OOP のアイデアと実践は関連性を保ちます。優れたオブジェクト設計があれば、おそらくアスペクトで拡張しやすくなります。

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

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

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

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

于 2008-10-24T09:16:57.540 に答える
1

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

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

于 2010-10-13T11:30:34.370 に答える