記事の紹介

この記事ではアスペクト指向プログラミングに対して扱います。

登場歴史

昔、プログラミングの規模は小さいものでした。例えば、ミサイルの射距離を計算したり単純な式を計算することに使われました。この時のプログラミング方式を手続き型プログラミングと言います。
手続き指向はすごく直観的です。なぜならソースコードを上から下へとざっと見るだけで実行されました。規模が小さかったためプログラミングを効率的に作成する方式の必要性がまだは言われなくなりました。
しかし、プログラムを一般企業から使用することになるに連れて、プログラムの規模が大きくなり始めます。
それにつれて、ソフトウェア開発は大きな危機に置かれるようになります。手続き方式プログラミングは大きなプログラムを作るには非効率的でした。
そこで開発されたのがオブジェクト指向プログラミングです。
オブジェクト指向プログラムはオブジェクトという革新的な概念を活用することによって、この危機を克服します。
しかし、プログラムの規模が大きくなるに連れてこのようなモジュールも中では中腹的なコードが生まれるようになりました。
これを横断的関心事と言います。その中でよく言われるのがトランザクション、ロギング、性能分析などです。
このような横断的関心事たちはいろんなモジュールを、言葉通り横断しながら、存在するようになります。
横断的関心事はAOPを理解するために重要な概念です。

横断的関心事のモジュール画

AOPの目的はこのような横断的関心事をモジュール化する方法を提示する事です。このようなコードの中腹を取り除いて理解しやすくしてプログラムの作成を簡単にし、簡単に管理できるようにしてくれます。

基本概念

一般的にアスペクトはコードとして分散されたり絡んでいて理解したり管理をしづらくします。潜在的に絡んでる関係のシステムや別々の言語で絡んでいる関係のないかんすうにロギングのような関数が分散します。つまり、ロギングを変更したら影響されてる全てのモジュール修正が必要です。アスペクトは表のシステムのの核心機能だけに限らずお互いにも絡んでます。

使用例

概念的にすごく単純なメソッドがある銀行業アプリケーションを考えてみよう。下記の例はあるアカウントから他のアカウントに送金するメソッドである。

void tranfer(Account fromAcc, Account toAdd, int amount) throws Exception {
if(fromAcc.getBalance() < amount ) {
		throws new InsufficientFundsException();	
}

fromAcc.withdraw(amount);
toAcc.deposit(amount);
}

しかし、このような送金方法は配置されたアプリケーションが次に必要なものだけを考慮している。現在、ユーザがこの作業を遂行するには権限があるかを検査する保安機能がない。データのセキュリティのためにカプセル化をしたほうが良い、診断のためにこの作業はシステムログに記録したほうが良い。などなど。。。
このような考えが次のように実装することができます。

void transfer(Account fromAcc, Account  toAcc, int amount, User user, Logger logger, Database database) throws Exception {
	logger.info(“Transferring money…”);

	if(!isUserAuthorised(user, fromAcc)) {
logger.info(“User has no permission.”);
throw new UnauthorisedUserException();
}


if(fromAcc.getBalance() < amount) {
	logger.info(“Insufficient funds”);
	thorow new InsufficientFundsException();
}

fromAcc.withdraw(amount);
toAcc.deposit(amount);

database.commitChanges(); //Atomic operation

logger.info(“Transaction sucessful”)
}

このような例で他の関心事たちは基礎的な機能(ビズネスロジック関心事)と一緒に後ろと絡んでる。トランザクション、セキュリティ、ロギングなどはすべて横断的関心事を指す。
いわゆるとうちらが急にアプリケーションに対してセキュリティ事項を変更しないといけないとしてみよう。プログラムの現在バージョン関連機能は数え知れないメソッドが分散されたように現れこのような変更点はかなりの努力が要求される。
AOPはプログラマが横断的関心事をアスペクトという独立的なモジュールで表現できるようにすることによってこの問題を解決しようとする。アスペクトはアドバイス(プログラム内の特定ポイントと結合されるコード)とインタータイプ(他のクラスに追加される構造的なメンバー)を含める。いわゆるセキュリティモジュールには銀行口座に接近する前に保安検査を遂行するアドバイスを含める事ができる。ポイントカットは誰かが銀行の接近する視点(ジョインポイント)を定義し、アドバイス本体内の検査と場所を一気で管理できるようになります。その上、良好なポイントカットは後のプログラム変更を予測できるんで他の開発者が銀行のアカウントに接近するするための新しいメソッドを作ったらアドバイスは実行時に新しいメソッド適用ができます。
なので上のれ台にアスペクトロギングを実装すると次のようになる。

aspect Logger {
	void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger) {
	logger.info(“Transferring money...”);
}

void Bank.getMoneyBack(User user, int transactionId, Logger logger ) {
	logger.info(“User requested money back.”);
}

// Other crosscutting code. 
}