web-dev-qa-db-ja.com

横断的関心事の例

cross-cutting concernの良い例は何ですか? wikipedia ページの医療記録の例は、私には不完全なようです。

特にこの例から、なぜロギングはコードの重複(scattering)につながるのでしょうか? (log("....")などの単純な呼び出しに加えて、大したことではないようです)。

core concerncross-cutting concernの違いは何ですか?

私の最終目標は、AOPをよりよく理解することです。

96
jlars62

横断的懸念を理解する前に、懸念を理解する必要があります。

Concernは、機能に基づいて分割されたシステムの一部を指す用語です。

懸念は2つのタイプです。

  1. 主な要件に対する単一の特定の機能を表す懸念は、中核の懸念として知られています。
    または
    システムの主要な機能は中核となる懸念事項として知られています。
    たとえば:ビジネスロジック
  2. 二次要件の機能を表す関心事は、横断的関心事またはシステム全体の関心事と呼ばれます。
    または
    横断的関心事は、アプリケーション全体に適用可能な関心事であり、アプリケーション全体に影響します。
    例:ロギング、セキュリティ、およびデータ転送は、アプリケーションのほとんどすべてのモジュールで必要とされる懸念事項であり、したがってクロスしています-カッティングの懸念。

礼儀

enter image description here

この図は、モジュールに分割された典型的なアプリケーションを表しています。各モジュールの主な関心事は、特定のドメインにサービスを提供することです。ただし、これらの各モジュールには、セキュリティロギングやトランザクション管理などの同様の補助機能も必要です。横断的関心事の例は「ロギング」です。これは、メソッド呼び出しをトレースすることでデバッグを支援するために分散アプリケーションで頻繁に使用されます。各関数本体の最初と最後の両方でロギングを行うと仮定します。これにより、少なくとも1つの関数を持つすべてのクラスが横断的になります。

(礼儀)

189
Premraj

横断的な関心事の唯一の最良の例は、取引行動です。たとえば、すべてのサービスメソッドにコミットコールとロールバックコールでtry-catchブロックを配置する必要がある場合は、忌避されます。 AOPが目的のトランザクション動作でカプセル化するために使用できるマーカーでメソッドに注釈を付けることは、大きな勝利です。

横断的関心事の例としてのもう1つの良い候補は認可です。誰がそれを呼び出すことができるかを示すマーカーでサービスメソッドに注釈を付け、メソッド呼び出しを許可するかどうかをAOPアドバイスに決定させることは、サービスメソッドコードでそれを処理するよりも望ましい場合があります。

AOPアドバイスを使用してロギングを実装すると、より柔軟になり、ジョインポイントを変更することでロギングされる内容を変更できるようになる可能性があります。実際には、プロジェクトでそれを頻繁に行うことはありません。通常、log4jなどのライブラリを使用すると、ロギングレベルとカテゴリでフィルタリングすることができ、必要に応じて実行時に十分に機能します。

中心的な関心事は、アプリケーションが存在する理由、アプリケーションが自動化するビジネスロジックです。輸送貨物を処理するロジスティクスアプリケーションがある場合、トラックにどれだけの貨物を詰め込めるか、またはトラックが配達物を降ろすのに最適なルートは何かを把握することが重要な懸念事項です。横断的な関心事は通常、ビジネスロジックとは別に保つ必要がある実装の詳細です。

41
Nathan Hughes

受け入れられた答えに加えて、横断的な関心事の別の例、リモーティングに言及したいと思います。エコシステム内の他のコンポーネントを、それらがプロセスで実行されているかのようにローカルに呼び出すだけだとします。場合によってはそうすることもあります。しかし、今はクラウドまたはクラスターに分散されたサービスを実行したいと考えています。アプリケーション開発者としてこの側面に注意する必要があるのはなぜですか?アスペクトは、誰にどのように電話をかけるかを見つけ出し、必要に応じて送信データをシリアル化し、リモートコールを発信します。すべてが進行中の場合、アスペクトはローカルコールを転送します。呼び出し先側では、アスペクトはデータをデシリアライズし、ローカル呼び出しを行い、結果を返します。

ここで、ログ出力などの「些細な」ことについて少し話しましょう。ほんの数週間前、私はクライアント用に複雑ではあるが大きすぎないコードベース(約25万行のコード)をリファクタリングしました。数百のクラスで、ある種のロギングフレームワークが使用され、別の数百のクラスで使用されました。その後、ログ出力が実際にあるはずのSystem.out.println(*)の数千行がありました。そのため、コードベース全体に散在する数千行のコードを修正することになりました。幸いなことに、IntelliJ IDEA(構造検索と置換)でいくつかの巧妙なトリックを使用して、アクション全体を高速化できましたが、それは些細なことだとは思わないでください!確かに、コンテキスト依存の強力なデバッグロギングは常にメソッドボディ内で発生しますが、メソッド呼び出しのトレース(インデントが適切に階層化されている場合でも)、処理済みまたは未処理の例外の両方のロギング、ユーザー監査(ユーザーロールに基づく制限されたメソッドなど)は、ソースコードを汚染することなく、アスペクトに簡単に実装できます。日常のアプリケーション開発者は、それについて考えたり、コードベースに散らばっているロガー呼び出しを見たりする必要さえありません。誰かがアスペクトを最新の状態に保つ責任があり、ロギング戦略またはロギングフレームワーク全体を一箇所で一元的に切り替えることさえできます。

他の分野横断的な懸念についても同様の説明を思いつくことができます。コードをクリーンに保ち、IMOが散らばったり絡まったりしないようにすることはプロ意識の問題であり、何もオプションではありません。最後になりますが、コードを読みやすく、保守しやすく、リファクタリングしやすくします。アーメン。

12
kriegaex