AspectScope による

クラスのインターフェース
やその振る舞いに及ぼす
アスペクトの影響の解析と
可視化
堀江 倫大 千葉 滋
東京工業大学
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