回答:
横断的関心事を理解する前に、関心事を理解する必要があります。
懸念は、機能に基づいて、分割されたシステムの一部を指す用語です。
懸念事項には次の2つのタイプがあります。
この図は、モジュールに分割された典型的なアプリケーションを表しています。各モジュールの主な関心事は、特定のドメインにサービスを提供することです。ただし、これらの各モジュールには、セキュリティログやトランザクション管理などの同様の補助機能も必要です。横断的関心事の例は「ロギング」です。これは、分散アプリケーションで頻繁に使用され、メソッド呼び出しのトレースによるデバッグを支援します。各関数本体の最初と最後の両方でログを記録するとします。これにより、少なくとも1つの機能を持つすべてのクラスがクロスカットされます。
横断的関心事の最も良い例は、トランザクション動作です。たとえば、すべてのサービスメソッドでcommitおよびrollback呼び出しを使用してtry-catchブロックを配置する必要があると、反発することになります。AOPがメソッドを望ましいトランザクション動作でカプセル化するために使用できるマーカーでメソッドに注釈を付けることは大きな勝利です。
横断的関心事の例としてのもう1つの良い候補は、承認です。誰がサービスメソッドを呼び出すことができるかを示すマーカーでサービスメソッドに注釈を付け、メソッド呼び出しを許可するかどうかをAOPアドバイスに決定させることは、サービスメソッドコードでそれを処理するよりも望ましい場合があります。
AOPアドバイスを使用してロギングを実装することで、柔軟性を高めることができるため、ジョインポイントを変更することで、ログに記録される内容を変更できます。実際には、プロジェクトがそれを頻繁に行うことはありません。通常、必要に応じて実行時にロギングレベルとカテゴリでフィルタリングできるlog4jなどのライブラリを使用すると、十分に機能します。
中心的な懸念は、アプリケーションが存在する理由、つまりアプリケーションが自動化するビジネスロジックです。配送貨物を処理するロジスティクスアプリケーションがある場合、トラックに梱包できる貨物の量、またはトラックが配達を降ろすのに最適なルートを把握することが、主要な懸念事項になる場合があります。分野横断的な問題は、通常、ビジネスロジックとは別に保持する必要がある実装の詳細です。
受け入れられた回答に加えて、横断的関心事の別の例として、リモート処理について触れておきます。たとえば、エコシステム内の他のコンポーネントを、プロセス内で実行されているかのようにローカルで呼び出したいとしましょう。たぶんいくつかのケースでは、彼らはさえします。しかし今は、クラウドまたはクラスターに分散されたサービスを実行したいと思います。なぜアプリケーション開発者としてこの側面を気にする必要があるのですか?ある側面は、誰がどのように呼び出すか、そして必要に応じて送信されたデータをシリアル化し、リモート呼び出しを行う方法を見つけることを処理します。すべてがプロセスで実行されている場合、アスペクトはローカルコールを転送するだけです。呼び出し先側では、アスペクトはデータをデシリアライズし、ローカル呼び出しを行い、結果を返します。
ここで、ログ出力のような「些細な」ことについて少し話しましょう。ほんの数週間前に、クライアント用に複雑であるが大きすぎないコードベース(約250K行のコード)をリファクタリングしました。数百のクラスで1種類のロギングフレームワークが使用され、さらに数百のクラスで使用されました。それから数千行のSystem.out.println(*)
ログ出力が本当にあったはずの場所。そのため、コードベース全体に散在する数千行のコードを修正することになりました。幸いなことに、IntelliJ IDEA(構造検索と置換)で巧妙なトリックを使用してアクション全体を高速化することができましたが、それは簡単なことではありませんでしたか。確かに、コンテキストに強く依存したデバッグロギングは常にメソッド本体内で発生しますが、メソッド呼び出しのトレース(適切にインデントされた出力で階層的にさえ)、処理された例外または処理されない例外の両方のロギング、ユーザー監査(への呼び出しのロギング)など、多くの重要なタイプのロギングユーザーロールに基づく制限されたメソッドなど)は、ソースコードを汚染することなく、さまざまな側面で簡単に実装できます。日常のアプリケーション開発者は、それについて考えたり、ロガー呼び出しがコードベース全体に散らばったりする必要さえありません。
他の分野横断的な懸念についても同様の説明を思いつくことができます。コードをクリーンな状態に保ち、IMOが散らばったり絡まったりしないようにすることは、専門知識の問題であり、オプションではありません。最後に重要なことですが、コードの読み取り、保守、リファクタリングを維持します。アーメン。
横断的関心事は、アプリケーションのタイプに関係なく常に存在する必要があるシナリオです。
たとえば、ログ、セキュリティ、パフォーマンスプロファイリング、ローカリゼーション、アクセシビリティ、トランザクションなど。ログを作成しているソフトウェアに関係なく、ログが必要です(それ以外の場合、デバッグまたは製品データから関連情報を取得する方法)。セキュリティ(認証/承認など)が必要なのは、認証されたユーザーのみが適切な特権セットでアプリケーションにアクセスできる場合です。アプリケーションのパフォーマンスを把握してから、プロファイリングを行う必要があります。アプリケーションが国際化されたユーザーによって(独自のローカライズされた言語で)使用されている場合、アプリケーションでそれをサポートする必要があります。アクセシビリティは、障害者が私たちのアプリケーションを使用するためのユーザビリティケースです。
アプリケーションがデスクトップベースかWebベースかなどに関係なく、本番環境で地理的にエンドユーザーが使用する必要がある場合は、クロスカットが必要です。これまで、私はアプリケーションについては何も言っていませんでしたが、本番環境のエンドユーザーにリリースする前に対処する必要のある懸念のリストを示しました。そしてそれはすべて横断的な関心事に関するものです(これはすべてのアプリケーション/メソッド/クラスによって、つまりさまざまなレベルで処理される必要があります)。