プログラミング言語/アスペクト言語

出典: フリー教科書『ウィキブックス(Wikibooks)』

アスペクト指向言語[編集]


アスペクト指向言語(Aspect Oriented Programming Language)は、アスペクト指向プログラミング(AOP)をサポートするプログラミング言語のことを指します。AOPは、プログラムの中での横断的関心事(クロスカットコンサーン)を処理するためのプログラミングのパラダイムであり、横断的関心事をコードから分離し、それらを独自のモジュールとして管理できるようにします。

アスペクト指向言語には、アスペクトの定義や結合の仕方を専門的に扱うための構文が組み込まれています。アスペクトを作成することで、横断的関心事を一元的に管理し、それらの関心事を含むすべてのモジュールを修正する必要がなくなります。アスペクト指向言語は、Javaのようなオブジェクト指向言語と組み合わせて使用されることが一般的ですが、独自の言語としても使用されます。

例えば、ログインする前に認証が必要なアプリケーションを考えてみましょう。通常、ログインに関する機能は多くの場所で使用されます。しかし、ログインに必要な認証は、アプリケーション全体で同じです。このような場合、アスペクト指向言語を使用して、ログイン認証の関心事を1つのアスペクトにまとめ、それを他のモジュールに関連付けることができます。それによって、アプリケーション全体で認証に関する修正を簡単に実装できるようになります。

アスペクト指向プログラミング[編集]

アスペクト指向プログラミング(Aspect Oriented Programming; AOP)は、オブジェクト指向プログラミング(Object Oriented Programming; OOP)の制限を解決することを目的とした開発手法です。

オブジェクト指向プログラミングは、データやメソッドをオブジェクトにカプセル化し、ポリモーフィズムを用いて複雑さを管理することで、ソフトウェア開発を容易にします。しかし、大規模なアプリケーションでは、同じ部分が複数の場所に現れる「クロスカットの懸念」が存在し、これに対応するために実装されたコードによって、カプセル化が崩壊し依存関係が増加することがあります。

AOPでは、クロスカットの懸念に対処するために、別のプログラミング構成でそのコードを扱い、自動的にOOPソースコードに織り込むことで、依存関係と複雑さを軽減することを目的としています。具体的には、AOPは、アスペクト(関心のある機能)を定義し、それらを特定のポイントカット(コードの断片)に割り当て、横断的に(クロスカット)動作するアドバイス(関心に応じた処理)を提供します。これにより、OOPのコードは通常通りコンパイルされ、アスペクトの関心ごとに処理を拡張することができます。

AOPは、JavaのAspectJや.NETのPostSharpなどの多数のプログラミング言語で実装されています。ただし、AOPはプログラミング言語の機能ではなく、プログラミング言語を補完する手法であるため、AOPを使用するためには特定の言語の理解と実装方法を学ぶ必要があります。

[編集]

AOPに適した分野の典型的な例として、ロギングが挙げられます。プログラマはしばしば、開発中のデバッグや配備後のバグ修正のために、プログラムの状態や流れを記録するためにロギングを使用します。OOPプログラムでは、ロギングはいくつかの可能な形を取ります。

  • すべてのオブジェクトは、グローバルなロガー・オブジェクトにアクセスでき、そのメソッドを呼び出してイベントや状態を記録します。
  • ロギングを必要とするすべてのオブジェクトは、ログに書き込むために同じコードを繰り返します。
  • 各オブジェクトは、それ自身のログを保持し、場合によってはファイルに保存します。

AOPが解決しようとする本質的な問題は、コードが複数の場所で繰り返されるため、保守が難しく、異なる構造体間の依存関係が増大することです。ロガーの動作を変更するには、2番目と3番目のケースでは、複数のファイルで同じコードを書き直す必要があり、ロガーの使い方を変更するには、すべてのケースで同じコードを書き直す必要があります。

そこで、ロギングをクロスカットで定義し、アスペクトで解決することで、プログラマはロギングを処理するアスペクトコードを書き、AOPの「ウィーバー」を使ってOOPソースにコードを注入し、それを通常のOOPコードとしてコンパイルすることができるようになりました。ロギング機能はクラスのソースコードから取り除かれ、1つの場所にまとめられ、ローカルに定義され、実装され、プログラムの残りの部分で個別に使用できる別の単一の構成要素として扱われるようになりました。

概要[編集]

理論的には、AOPはSeparation of Concernを実現するための方法である。 オブジェクトはしばしば、概念的に異なる複数の関心事を扱うように要求される。 例えば、売上入力アプリケーションのインボイスは、購入者の身元や購入した品目などの明らかなプロパティを含んでいます。しかし、インボイスオブジェクトは、その動作を記録する方法、データベースで自身を持続する方法、購入者の信用限度を確認する方法、期限を過ぎたときにフラグを立てる方法なども要求されることがあります。 その結果、インボイスクラスは大きく、複雑になり、維持するのが難しくなる可能性がある。 これらの懸念事項は、クラスが扱うべき正当なものですが、OOPの原則によれば、内部で目に見えないように処理されなければなりません。 もし、これらの懸念事項が他のオブジェクトと遠い関係で共有されると、関係するクラスは不必要に複雑になるだけでなく、その複雑さが複数の場所で繰り返されることになります。

いくつかの定義が助けになる。

クロスカット関心事」または「クロスカット」とは、OOPアプリケーションの設計の中で、他に関連性のないいくつかの異なる部分で同時に発生するあらゆる部分のことです。 ログの記録は明らかな例ですが、永続化もその一つです。 銀行アプリケーションでは、多くの異なるオブジェクトを同じ方法で保存し、取り出す必要があります(例えば、リレーショナルデータベース)。 永続化とは、アプリケーションのオブジェクトに対するクロスカットである。

結合点とは、OOPコード内の意味的に定義可能な点で、編み手が識別できるものである。 ロギングの例では、プログラマーはコールスタックを記録したいので、ロガーはすべての関数の入口と出口を記録する必要がある。

一連の結合点は、まとめて「ポイントカット」で識別されます。 ポイントカットは、見つけるべき結合点を定義するAOPコードです。

ポイントカットは、結合ポイントを特定するだけでなく、そのポイントに作用するコードも含んでいます。 このコードはadviceまたはadvicesと呼ばれる。

つまり、aspectとは、AOPモジュールによって処理される特定のクロスカットを定義するポイントカットの集合である。 実際には、ロギングの例に対するソリューションは、プログラマーがロギングを発生させたい結合点を特定するポイントカットを定義するアスペクトモジュールである。 結合点を特定した後、プログラマはAOPモジュールにアドバイスを書き込み、ウィーバーはそのコードをOOPソースコードに注入して、コードのコンパイルの前段階とする。

この時点では、AOPはクラスからユーティリティコードを引き出して一元化する方法に過ぎないように見えますが、これはAOPの長所の1つです。 しかし、AOPはもっと複雑な問題を分離することができます。 請求書の例では、請求書には支払期限があることを述べました。 同様に、私たち自身の支払いにも期限がある場合があります。 この「期限切れ」の懸念は、invoiceとpayableの両方のオブジェクトの構築または初期化に関するポイントカットを定義するアスペクトとしてカプセル化することができる。 これらの結合点では、期限切れメンバを両方のクラスに追加し、期限切れ監視システムに請求書/支払明細を登録し、今後の期限に関する日次レポートを作成するコードを追加することができます。 支払期限を追跡するコードは、単一のモジュールに移動され、invoice/payableオブジェクトの複雑さが減少し、invoice/payableクラスと期限監視システムの間の依存関係がなくなり、システムの保守と変更が容易になりました。

実装[編集]

現在、AOPのプラットフォームとして最も普及しているのは、Java言語の拡張版であるAspectJです。 ここで例に挙げるのは、この言語です。