AspectJ を使ったデザインパターンの改善と支援

asato <asato@ncfreak.com>

最終更新日 : 2004/6/5 (2002/9/3 より)


このドキュメントでは、AspectJ によるデザインパターンの実装を考えます。AspectJ を使うことにより各デザインパターンの実装を考えたときに、どのようなバリエーションが存在するのかを調査しています。いくつかのバリエーションは、それほど実用的ではなく、しかし、いくつかについては設計上において考慮の必要な選択肢となります。

このドキュメントの目的は、AspectJ を使って各デザインパターンにおける代表的な(あるいは唯一)の実装例を紹介するのでは なく、考えられるすべてのバリエーションを列挙し、様々な状況においてそれぞれの実装の利点や欠点を調査することです。また、AspectJ の言語的な機能の視点から、デザインパターンを深く理解することも目的としています。


YES! かなり下書きです。メモです。書きっぱなしです。垂れ流しです。内容も、間違っている部分の方が多いと思います(ほとんどかも!)! マジにウソくさい内容です。一部の記述はパターン形式っぽく書いてますが、アンチパターン かもしれません!

"AspectJ + デザインパターン" というネタについてのより信頼できるリソースとしては、以下のものを読む方が適切かと思われます (僕の AspectJ の使い方と全然違う! たぶん僕のほうが間違ってる!)。

それから、内容についてさらに注意:

テスト環境

デザインパターン再考

AspectJ を使ってデザインパターンを実装しようと考えるにつれて、デザインパターンの見方が変わっていくことに気がつきました。デザインパターンとは何なのでしょうか? 構造のことでしょうか? どうなっていればデザインパターンでしょうか? どこでまでがデザインパターンでしょうか?

「パターンハッチング」ではパターンに対する誤解の 1 つとして「パターンとはコンテキスト (文脈) における問題の解決策である」というパターンに対する定義をあげています。また、以下のような反例を挙げています。

コンテキストにおける問題の解決策だけでは不十分らしいのです。足りないのは

Factory Method

なぜ役に立つのか

基本的な考慮点

ソースコードは利用できるのかどうか

AspectJ を利用する場合、ソースコードがなければ行えることは制限される。ソースコードが利用可能でなければ Introduction はできない。

ソースが利用できる場合の例:State クラスのソースコードが利用できる

package dp;

import java.lang.reflect.Method;

public class Client {

	public static void main(String[] args) {

		Method[] methods = State.class.getMethods();

		for(int i = 0 ; i < methods.length ; i++) {
			if ( methods[i].getName().startsWith("handle") ) {
				System.out.println( methods[i] );
			}
		}
	}
}
package dp;

public class State {
	public void handleA() {}
	public void handleB() {}
}
package dp;

public aspect StateAspect {
	public void State.handleC() {}
}
public void dp.State.handleA()
public void dp.State.handleB()
public void dp.State.handleC()
ソースが利用できない場合の例:State クラスのソースコードは利用できない
public void dp.State.handleA()
public void dp.State.handleB()

そのソースコードは誰のものかどうか

自らが提供しているフレームワークであり、ソースは利用できる

単なる置換えが目的なのかどうか

Introduction の能力

Introduction のできることできないこと

できること: できないこと: メモ:

Introduction 使用の適切な場合

Introduction 使用の不適切な場合

AspectJ を使ったソフトウェア開発のシナリオの種類

AspectJ を使っての、いくつかのソフトウェア開発のシナリオが考えられます。
シナリオ 1 シナリオ 2 シナリオ 3
アプリケーションの開発
ライブラリの使用 ×
バイトコード・ウィービング × ×

シナリオ 1 では、(javac の代わりに) AspectJ を使ってアプリケーションの開発を行います。

シナリオ 2 では、AspectJ を使ってアプリケーションの開発を行うのに加えて、外部ライブラリを使用します。しかし、バイトコードのウィービングは行いません。

シナリオ 3 では、AspectJ を使ってアプリケーションの開発を行うのに加えて、外部ライブラリを使用します。さらに、その依存しているライブラリに対して、何らかのバイトコードのウィービングも行います。

このように、特定のシナリオが、ある AspectJ によるデザインパターンの実装にも影響を与えます。シナリオ 1 では、アプリケーション内での AspectJ によるデザインパターンの実装が考えられます。シナリオ 2 では、アプリケーションが依存する特定のライブラリに対してのデザインパターンの実装が考えられます。シナリオ 3 では、特定のライブラリに対して、バイトコード・ウィービングを行うことによる、特定のデザインパターンの実装方法が考えられます。

デザインパターンと AspectJ

AspectJ を用いた AOP が威力を発揮しそうな場面として以下のものがある:

AspectJ を使って以下のことにトライする。

デザインパターンの欠点の種類

AspectJ を使ったデザインパターンに関するテクニックの種類

AspectJ を使ったデザインパターンに関するテクニックの種類には、大きくわけて以下の 3 つのテクニックが考えられます:

関連研究

異なる言語の特徴(あるいはパラダイム)が、デザインパターンの実装においてどのような影響をもたらすのかを調査した研究は、それほど多くありません。

GoF らによるデザインパターンの原典では、C++ と Smalltalk による、オブジェクト指向のパラダイムの視点からの実装が紹介されています [1]。

このドキュメントと最も関連があるのは、Hannemann と Kiczales による、AspectJ による GoF のデザインパターンの実装です [2]。彼らの視点は、どちらかといえば、再利用可能なデザインパターンを実装することにあるように見えます。

参考文献

注意書き

役割の項目で使っているタグ (<< >>) は、The UML Profile for Framework Architectures からのものを使用しました (Appendix B : UML-F tags of the GoF framework patterns )。

参考にしたもの

デザインパターン全般について参考にしたもののリストです。各パターンに特別に関係のある文献は、各パターンの参考文献の節で紹介しています。

更新履歴

todo