クラスのインターフェース やその振る舞いに及ぼす アスペクトの影響の解析と 可視化 堀江 倫大 千葉 滋 東京工業大学 1 モジュラープログラミング 全体をモジュールに分割 モジュール(=クラス)の (インタフェースの)仕様を決める 仕様だけを見てプログラミング クラスの仕様: シグネチャ + メソッドの振る舞い 情報隠蔽 内部実装は見なくてすむ 2 Java の場合 クラスの仕様と実装を一緒に考える 例) javadoc コメント class Line extends Shape { : /** * moves this shape dx along the x axis * and dy along the y axis. */ public vod moveBy(int dx, int dy) { p1.setX(p1.getX() + dx); p1.setY(p1.getY() + dy); p2.setX(p2.getX() + dx); p2.setY(p2.getY() + dy); } } メソッドの仕様 (javadoc コメント) メソッドの実装 3 AspectJ の場合 例:図形エディタへの機能追加 事前条件を追加するアスペクトを定義 Point クラスの setX、setY メソッドの振る舞いを変更 図形エディタのウィンドウ サイズ (0 < x < 100、 0 < y < 50) 内に図 形は描画されなければならない 50 × 100 aspect Contract { before(int x) : call(void Point.setX(int)) && args(x) && within(Shape+) { if (x < 0 || 100 < x) throw new IllegalArgumentException(); } before(int y) : call(void Point.setY(int)) && args(y) && within(Shape+) { if (y < 0 || 50 < y) throw new IllegalArgumentException(); }} 4 アスペクト指向(AOP)に対する批判 モジュラープログラミングが不十分 仕様だけを見てプログラミングできない class Line extends Shape { 正しくなくなる : /** * x 軸方向に dx、y 軸方向に dy だけ * 直線を平行移動させる */ public vod moveBy(int dx, int dy) { p1.setX(p1.getX() + dx); p1.setY(p1.getY() + dy); p2.setX(p2.getX() + dx); p2.setY(p2.getY() + dy); }} aspect Contract { : if (x < 0 || 100 < x) throw new IllegalArgumentException(); : } 5 仕様の間の依存関係 アスペクトによって呼び出しの上流・下流の仕様も変わる class MultiLines { private List lines; : /** * x 軸方向に dx、y 軸方向に dy * だけ多重線を平行移動させる class Line { : */ /** void moveBy(int dx, int dy) { * x 軸方向に dx、y 軸方向に dy class Point { private int x, y; for (Iterator it = lines.iterator(); * だけ直線を平行移動させる : it.hasNext();) */ ((Line) it).moveBy(dx, dy); public vod moveBy(int dx, int dy) { /** x 座標の値を設定 }} */ p1.setX(p1.getX() + dx); void setX(int nx) { : x = nx; }} }} aspect Contract { …. 6 } 開発ツール:AspectScope AspectScope がそれぞれを織り込む アスペクト 実装の変更 仕様の変更 pointcut-advice アドバイスのコメント class Line extends Shape { : /** * x 軸方向に dx、y 軸方向に dy だけ * 直線を平行移動させる */ public vod moveBy(int dx, int dy) { p1.setX(p1.getX() + dx); p1.setY(p1.getY() + dy); p2.setX(p2.getX() + dx); p2.setY(p2.getY() + dy); }} Weave Weave aspect Contract { /** * 直線の両端の x 座標は 0 以上 100 以下 * に制限される */ before(int x) : … { if (x < 0 || 100 < x) throw new IllegalArgumentException(); } : }} 7 変更後の仕様はツールが表示 Eclipse プラグインとして開発 8 織り込まれた仕様の表示 AspectScope のテキストエディタ マーカー: 仕様が変わっている箇所 javadoc コメント: 変更後のメソッドの振る舞い アスペクトが追加したコメント 9 アスペクト中の仕様の変更点の記述 comment アノテーション アドバイスのコメント 織り込み先ごとに別々のコメントを用意 /** @comment * The set value x should be no fewer than 0, nor more than 100 * only if the caller is the subclasses of Shape * * @comment (execution(void Line.moveBy(int, int))) * The horizontal position of both the starting point and the end * point should be no fewer than 0, nor more than 100 * * @comment (execution(void MultiLines.moveBy(int, int))) * The horizontal position of this line should be no fewer than 0, * nor more than 100 */ before(int x) : call(void Point.setX(int)) && args(x) && within(Shape+) { … } 10 呼び出しの上流・下流にも織り込み メソッドごとに異なるコメントを織り込む class MultiLines { private List lines; : /** class Line { : class Point { * x 軸方向に dx、y 軸方向に dy /** private int x, y; * だけ多重線を平行移動させる * x 軸方向に dx、y 軸方向に dy : * 多重線の x 座標は 0 以上 100 * だけ直線を平行移動させる /** x 座標の値を設定 * 直線の両端の x 座標は * 以下の範囲内に制限される * Shape のサブクラ */ * 0<x<100 に制限される * スから呼ばれたとき void moveBy(int dx, int dy) { */ for (Iterator it = lines.iterator(); public vod moveBy(int dx, int dy) { * だけ 0<x<100 に it.hasNext();) * 制限される p1.setX(p1.getX() + dx); ((Line) it).moveBy(dx, dy); */ : }} void setX(int nx) { }} x = nx; aspect Contract { }} /** @comment… */ 11 } コメントの織り込み先の指定 織り込み先の条件指定 条件なし execution( 特定のメソッド within( class pattern ) 特定のクラス内、パッケージ内のメソッド (例) within(* csg.figures.*) caller( method pattern ) int ) Line moveBy csg.figures Point Line Arrow Rectangle … Rectangle moveBy n 段前の呼び出し階層 同様の処理を行うメソッド Contract Triangle moveBy Point setX 12 outline ビュー クラスの中で定義されたメソッドとフィールドの列挙 アスペクトによって変更されていたらアイコン( )を表示する ソースコードを見る必要はない UndoCmdAspect によって拡張 13 実アプリケーションでの調査 目的 アスペクトの織り込みにより、仕様が変わっているか 織り込み先ごとに異なるコメントを必要としているか 対象アプリケーション アプリケーション Health Watcher (HW) [A. Rashid ら ‘07] クラス数 692 (LOC: 9,591)、アスペクト数 25 (LOC: 1,989) アスペクトの使用方法は5通り Web デザインパターン、例外処理、永続化、トランザクション、ロギング 14 AspectScope の適用結果 必要性が確認された 記述したコメントの種類と追加された箇所の数 拡張したメ 呼ばれ 呼び出し 呼び出し 呼び出し ソッド数 る側 1階層上 2階層上 3階層上 パターン Observer Command Factory State 17 3 0 15 17 0 NA 15 17 3 NA 14 0 0 NA 13 0 0 NA 10 呼び出し 呼び出し 6階層上 9階層上 0 0 NA 5 0 0 NA 2 Observer パターンにおける追加コメントの例 setPassword: “Calls <code>updateObserver</code> after setting the new password of the employee to update the Observer.” executeCommand: “Updates the information of the employees by calling <code>updateObserver</code>.” 15 関連研究: Aspect-Aware Interface (AAI) AAIの概念を提案した論文 [G. Kiczales ら ‘05] 「AOP には OOP とは異なる新しいインターフェース AAI が存在する 」 AspectScope は AAI を具現化したツール 変更後の仕様の表現を工夫 コメントとして書く ツールで変更後のコメントを見る AAIは上流・下流への影響を考慮していない 16 関連研究: Open Module AOP の能力を制限して、モジュラープログラミング を可能にしている クラス側からは、どこが拡張されるかが分かる Module に公開されたポイントカットしか、アスペク トは拡張できない Open 将来の機能拡張に備えて ポイントカットを予め公開して おくのは難しい AOP module FigureModule { class Line; expose call(void Point.setX(int)) || call(void Point.setY(int)); } の利点を損なう 17 まとめ: AspectScope はモジュラーな AOPを支援 AspectScope はアドバイスだけでなく、アドバイスの コメントも織り込む ツールが変更された仕様を表示 元の実装の javadoc + アスペクトが追加した javadoc エディタのマーカー、アウトラインビューによる更新点の通 知 Eclipse プラグインとして開発 M. Horie, S. Chiba. “AspectScope: An OutlineView for AspectJ Programs”, Journal of Object Technology 18
© Copyright 2024 ExpyDoc