AspectScope による アスペクト指向プログラ ミングの支援 数理・計算科学専攻 千葉研究室 堀江 倫大 指導教員: 千葉 滋 1 モジュラープログラミング 全体をモジュールに分割 モジュール(=クラス)の (インタフェースの)仕様を確定 仕様だけを見てプログラミング クラスの仕様: シグネチャ + メソッドの振る舞い 仕様は変えない 情報隠蔽 内部実装は仕様を満たしていれば自由に変えてよい 2 AOP は モジュラープログラミングができない よくある批判 アスペクトが仕様と実装の一貫性を壊す可能性がある 他のモジュールの実装を、仕様を無視して変更できてしま う AOP の obliviousness の負の側面 元のクラスの実装は改変されない 仕様だけを見てプログラミングできない あちこちの実装を見る必要がある モジュール内部の実装 そのモジュールに影響をおよぼしていそうなアスペクトの実装 3 例:リファクタリング 契約のためのアスペクトを定義 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 アスペクトにより仕様と実装が食い違う コールグラフ中のメソッド全体に食い違いの影響が及ぶ ポイントカットが指定したメソッドだけではない x 軸方向に 点の xdx、y dx, 座標を設定する y 軸方向に 軸方向にdy dyだけ だ 直線を移動させる け多重線を移動する ++ class MultiLines extends Shape{ 直線の両端の x 座標は 0 以上 100 以下、 多重線の xShape 座標は 0 以上 100 以下 のサブクラスから呼び出されたとき y 座標は 0のみ、 以上 50 の範囲内に制限される 0 <以下に制限される x < 100 に制限される private List lines; : void moveBy(int dx, int dy) { for (Iterator it = lines.iterator(); it.hasNext();) ((Line) it).moveBy(dx, dy); }} + class Line extends Shape { private Point p1, p2; : void moveBy(int dx, int dy) { p1.setX(p1.getX() + dx); : }} class Point extends .. private int x, y; : void setX(int nx) { x = nx; }} call(void Point.setX(int)) && within(Shape+) 5 開発ツール: AspectScope AOPでのモジュラープログラミングを支援する アスペクトの中に、実装の変更だけでなく、それに合わせ た仕様の更新も記述させる 変更部分を説明した追加 javadoc コメント メソッドごとに、それぞれの抽象化に合わせ異なるコメントを記述 可能 ツールが更新後の仕様を表示 元の javadoc コメント アスペクトが追加した javadoc コメント 変更点を知らせるテキストエディタのマーカー、アウトライ ンビュー 6 Eclipse プラグインとして開発 エディタ、ビューを拡張 7 更新後の仕様の表示 AspectScope のテキストエディタ マーカー: 仕様が変わっている箇所を示す javadoc コメント: 更新後のメソッドの振る舞い アスペクトが追加した javadoc 8 outline ビュー クラスの中で定義されたメソッドとフィールドの列挙 アスペクトによって変更されていたらアイコン( )を表示する ソースコードを見る必要はない UndoCmdAspect によって拡張 9 メソッドの抽象化に沿ったコメントの追加 The horizontal position of this line should be no fewer than 0, nor more than 100 class MultiLines { The horizontal position of both the starting point and the end point should be no fewer than 0, nor more than 100 private List lines; : void moveBy(int dx, int dy) { for (Iterator it = lines.iterator(); it.hasNext();) ((Line) it).moveBy(dx, dy); }} class Line { private Point p1, p2; : The set value x should be no fewer than 0, nor more than 100, only if the caller is the subclasses of Shape void moveBy(int dx, int dy) { p1.setX(p1.getX() + dx); : }} call(void Poin.setX(int)) && within(Line) class Point { private int x, y; : void setX(int nx) { x = nx; }} 10 アスペクトによる仕様の更新の記述 comment アノテーション 変更部分を説明する追加コメントの定義 アドバイスを定義するときに一緒に記述 /** @comment * The set value x should be no fewer than 0, nor more than 100 * * @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(Line) { … } 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 comment アドバイス AspectScope 独自のアドバイス メソッドに元々コメントがない場合、comment アドバ イスを利用してコメントを織り込む ポイントカットのみ指定可能 不要になったら unweave 可能 execution (例) Line.getDistance メソッドへのコメントの織り込み class Line { int getDistance(Point p) { : } : } /** Returns the distance from this line */ comment() : execution(int Line.getDistance(Point)) {} 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 ロギングアスペクト 呼び出し側に仕様変更を反映させる必要は必ずし もない ロギングはプログラムのセマンティクスを変更しない アスペクト名 拡張した メソッド数 呼ばれ る側 呼び出し 1階層上 呼び出し 2階層上 HWLogging 2 1 (2) (1) public synchronized static HealthWatcherFacade getInstance() { if (singleton == null) singleton = new HealthWatcherFacade(); return singleton; } 16 関連研究: Aspect-Aware Interface (AAI) AspectScope が基本とする考え方を最初に提案 アイデアを提示した論文 [G. Kiczales ら ‘05] には OOP とは異なる新しいインターフェースAAI が存在する 変更後の仕様の表現方法が異なる AOP call、get、set ポイントカットの表現について具体的な言及はない メソッドの振る舞いの表現は扱っていない AspectScope は、javadoc コメントを使って表現 17 関連研究: AJDT ポイントカットによって選択されたジョインポイントに マークを表示するのみ 広範囲に広がるアスペクトの影響は表現できない 局所的な表示 (例) call ポイントカットの場合 caller にしか表示されない callee には表示なし caller callee 18 関連研究: Open Module AOP の能力を制限して、モジュラープログラミング を可能にしている クラス側からは、どこが拡張されるかが分かる Module に公開されたポイントカットしか、アスペク トは拡張できない Open 将来の機能拡張に備えて ポイントカットを予め公開して おくのは難しい AOP module FigureModule { class Line; expose call(void Point.setX(int)) || call(void Point.setY(int)); } の利点を損なう 19 まとめ AspectScope: AspectJ におけるモジュラープログラミングを支援 アスペクトの中に、実装の変更だけでなく、それに合わせ た仕様の更新も記述させる comment アノテーションによる仕様の追加 comment アドバイス ツールが更新後の仕様を表示 テキストエディタにおける javadoc コメントの表示 エディタのマーカー、アウトラインビューが更新点を知らせる Eclipse プラグインとして開発 M. Horie, S. Chiba. “AspectScope: An OutlineView for AspectJ Programs”, Journal of Object Technology 20 今後の課題 コールグラフごとのコメントのモジュール化 現在は、ひとつのアドバイスに複数のコメントを羅 列している プログラムの改変に弱い構造 インターフェースに現れる冗長なコメントの集約 (例) setX、setY メソッドは moveBy メソッド内でそれぞ れ2回ずつ呼び出される 同じコメントが2回ずつ表示されてしまう comment アドバイスを利用することを検討 21
© Copyright 2025 ExpyDoc