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

StackOverflow https://stackoverflow.com/questions/232884

  •  04-07-2019
  •  | 
  •  

質問

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

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

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

役に立ちましたか?

解決

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

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

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

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

set-method が 3 つあれば問題ありません。200 (仮説) がある場合、これをあらゆる場所に追加するのは非常に困難になります。また、新しい set-method を追加するときは必ずこれを最後に追加することを忘れないようにしてください。そうしないとバグが発生するだけです。

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

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

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

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

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

ここで、AOP がどのように問題をエレガントに解決するかがわかりますか?実際、ここで説明したことはすべてコンパイル時に実行できます。AOP プリプロセッサはソースを変更するだけです (例:クラス自体をコンパイルする前に、すべての set-pointcut メソッドの最後に Display.update() を追加します。

ただし、この例は、AOP の大きな欠点の 1 つも示しています。AOP は実際には、多くのプログラマが「問題だと考えていること」を行っています。アンチパターン」。正確なパターンは「」と呼ばれます。離れた場所でのアクション".

離れた場所でのアクションは、 アンチパターン (認識されている一般的な error) で、1 つの部分で動作します のプログラムは、 識別が困難または不可能 の別の部分での操作 プログラム。

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

アップデート

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

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

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

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

他のヒント

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

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

AOPはOOPの代替としてではなく、より良いアドオンとして、 コードをよりクリーンで疎結合にし、ビジネスロジックに集中させます。 AOPを適用することで、2つの大きなメリットが得られます:

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

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

この質問に対する一般的な答えはないと思いますが、注目すべきことは、AOPはOOPを置換せず、いわゆる専制政治に対処する特定の分解機能を追加することです支配的な構成 1 )(または横断的関心事)。

特定のプロジェクトで使用するツールと言語を制御している限り、特定のケースで確実に役立ちますが、アスペクトの相互作用や< a href = "http://www.eclipse.org/ajdt" rel = "nofollow noreferrer"> AJDT でプログラムを理解します。

Gregor Kiczalesは、Google Tech TalksでAOPに関する興味深い紹介講演を行ったことがあります。ぜひご覧ください:アスペクト指向プログラミング:モジュール方式の急進的研究

まず、AOPはOOPを置き換えません。 AOPはOOPを拡張します。 OOPのアイデアと実践は関連性を保ちます。オブジェクトを適切に設計することで、アスペクトを拡張しやすくなります。

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

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

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

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

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

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

OOP は主にビジネスロジックの整理に使用され、 AOP 機能しないものの整理に役立ちます監査、ロギング、トランザクション管理、セキュリティなど

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top