200 likes | 282 Views
AspectScope によるアスペクトとクラスのつながりの視覚化. 堀江倫大 千葉滋 東京工業大学. アスペクト指向言語. ジョインポイント プログラム中のイベントが発生するとき メソッド呼び出し時、フィールド参照時など ポイントカット どのイベント発生時にコードを実行するか 例 : Graphics クラスの draw メソッドを呼び出すとき プリミティブなポイントカット set: フィールドへの代入、 get: フィールドの参照、 execution: メソッドの実行、 call: メソッド呼び出しなど アドバイス
E N D
AspectScopeによるアスペクトとクラスのつながりの視覚化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: 代表的なアスペクト指向言語のひとつ 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! モジュール(クラス) アドバイス メソッド
AJDTcallポイントカット (get、setポイントカット) • アドバイスは呼び出し側のメソッドの前後で実行されるものととらえる after(): call(void Point.setX(int)) { Display.update(); } 呼び出し側クラス AJDTエディタ
AspectScopecallポイントカット (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(); }
Shape … … * 1 Point setX(int x) setY(int y) … Line setP1(Point p1) setP2(Point P2) … Rectangle … … … Display update() … 具体例1: Observer アスペクト • Setter メソッドが呼び出されるときにアドバイスが実行される 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エディタ AJDTは呼び出し側のどの箇所でログ出力が行われるかを表示する before() : call(void Graphics.draw(Image)) && within(Canvas) { System.out.println(…); } AspectScopeは呼ばれる側がどう拡張されるかを表示する
関連研究 • Aspect-Aware Interface [Kiczalesら、‘05] • AspectScopeと基本的な考えは同じ • 概念的な考えのみを提案 • call、get、setポイントカットに関する具体的な提案はない • javadocコメントに関する考察もない • Classbox/J [Bergelら、‘05] • ある条件化でのみ有効なクラスの拡張を定義できるという考えが類似 • しかし、アスペクト指向言語ではない
まとめ • AspectScope: AspectJ用のプログラミングツール • クラスのアウトラインを表示 • 呼ばれる側のクラスがどのように拡張されたかを表示 • javadocコメントを集めることで、拡張の詳細を表示 • モジュールインタフェースの拡張なしでモジュール間の結びつきを表現