AspectScope によるアスペクトとクラスのつながりの視覚化 堀江倫大 千葉滋 東京工業大学
アスペクト指向言語 ジョインポイント ポイントカット アドバイス プログラム中のイベントが発生するとき メソッド呼び出し時、フィールド参照時など ポイントカット どのイベント発生時にコードを実行するか 例: Graphicsクラスのdrawメソッドを呼び出すとき プリミティブなポイントカット set: フィールドへの代入、 get: フィールドの参照、 execution: メソッドの実行、 call: メソッド呼び出しなど アドバイス ポイントカットが指定したタイミングで実行する処理 例: ログ出力処理
ログ出力 オブジェクト指向では、Logger クラスを定義して直接利用 ログ出力させたい箇所に挿入 ログ出力コードを取り除きたいときは挿入したコードを削除する必要 class Canvas { Image img; : void paint(Graphics g) { Logger.log(“log”); g.draw(img); } class Logger { public static void log(String msg) { System.out.println(msg); }
アスペクト指向の利用 AspectJ: 代表的なアスペクト指向言語のひとつ アスペクト aspect LogAspect { ポイントカット Graphics クラスの draw メソッド呼び出し前に Logger.log メソッドを実行 アスペクト aspect LogAspect { ポイントカット pointcut logged() : call(void Graphics.draw()); アドバイス before() : logged() { //ログ出力 Logger.log(“log"); } class Canvas { Image img; : void paint(Graphics g) { g.draw(img); } class Graphics { : void draw(Image img) { }}
アスペクト指向 モジュール間の結びつきを緩める 利点: クラスの定義を変更せずに、アスペクトにより振 る舞いを変更することが可能 欠点: モジュール間の結びつきが見えなくなってしまう 欠点を補うため、これまで様々な研究が成されてきた AJDT(AspectJ Development Tools) XPI(Crosscutting Programming Interface) Open Modules など
モジュール間の結びつきを「見える化」 従来の多くの研究 モジュールインターフェースを拡張して表現 モジュール(クラス) メソッド アドバイス イベント(ポイントカット) モジュール(クラス) メソッド
AJDT AJDT エディターと Visualiser ビュー ポイントカットによって選択されたジョインポイントを表示 アドバイスが結びつく「イベント」の発生位置を示す カプセル化が壊れる AJDTエディター Visualiserビュー
AspectScope の提案 クラスのアウトラインビューア AspectJ 用の Eclipse プラグイン アスペクトによって織り込まれたクラスのメンバのアウトラインを表示する 各メンバをインターフェースとして列挙し、その仕様の詳細を表示 outline Javadoc
AspectScope の「見える化」 モジュールインターフェースの拡張なしで モジュール間の結びつきを表現 モジュール(クラス) メソッド 従来の枠組みのままでアスペクトに対応 アスペクトはモジュールのメソッドの挙動を拡張すると考える Good! アドバイス モジュール(クラス) メソッド
AJDT callポイントカット (get、setポイントカット) アドバイスは呼び出し側のメソッドの前後で実行されるものととらえる after(): call(void Point.setX(int)) { Display.update(); } 呼び出し側クラス AJDTエディタ
AspectScope callポイントカット (get、setポイントカット) 呼ばれた側のメソッドが拡張されたととらえる after(): call(void Point.setX(int)) { Display.update(); } 呼ばれる側のクラス AspectScope
within、cflow ポイントカット 条件付き拡張 条件的な拡張とみなす after(): call(void Point.setX(int)) && within(Line) { Display.update(); } 条件付き拡張
javadoc コメントによる拡張の説明 ソースコードからコメントを集めて独自の javadoc コメントを表示 setXメソッドの実装から抽出 ポイントカットの実装から抽出 アドバイスの実装から抽出
pointcut の説明 ポイントカットの定義を自然言語で表現 ワイルドカードの 「*」、「+」、「..」は 具体的な名前に置き換えられる void setX(int) pointcut move() : call(void Shape+.set*(int)) || call(void Shape+.moveBy(..)); ワイルドカードの 「*」、「+」、「..」は 具体的な名前に置き換えられる after(): move() && within(Line) { Display.update(); }
具体例1: Observer アスペクト Setter メソッドが呼び出されるときにアドバイスが実行される Shape … Point setX(int x) setY(int y) Line setP1(Point p1) setP2(Point P2) Rectangle Display update() * 1 LineクラスのsetP1メソッド内でsetXメソッドが呼ばれるときにはアドバイスは実行しない。 pointcut change() : call(void Shape+.set*(..)); after(): change() && !cflowbelow(change()) { Display.update(); }
AspectScope vs. AJDT AspectScope AJDTエディタ AJDT では呼び出し側で ジョインポイントシャドウ を表示するだけ AspectScope は、setP1 メソッドが呼ばれるときには1度だけupdate メソッドが呼ばれることが表示される。
具体例2: Loggingアスペクト Canvas クラス内で Graphics クラスの draw メソッドを呼び出すときにログを出力する class Canvas { Image image; : void paint(Graphics g) { g.draw(image); } aspect LoggingAspect { before(): call(* Graphics.draw(..)) && within(Canvas) { System.out.println(“log”); }
AspectScope vs. AJDT AspectScope AJDTエディタ before() : call(void Graphics.draw(Image)) && within(Canvas) { System.out.println(…); } AspectScopeは呼ばれる側がどう拡張されるかを表示する
関連研究 Aspect-Aware Interface [Kiczalesら、‘05] Classbox/J [Bergelら、‘05] AspectScopeと基本的な考えは同じ 概念的な考えのみを提案 call、get、setポイントカットに関する具体的な提案はない javadocコメントに関する考察もない Classbox/J [Bergelら、‘05] ある条件化でのみ有効なクラスの拡張を定義できるという考えが類似 しかし、アスペクト指向言語ではない
まとめ AspectScope: AspectJ用のプログラミングツール クラスのアウトラインを表示 呼ばれる側のクラスがどのように拡張されたかを表示 javadocコメントを集めることで、拡張の詳細を表示 モジュールインタフェースの拡張なしでモジュール間の結びつきを表現