アスペクトを用いた表明の記述

アスペクトを用いた表明の記述
石尾 隆†,神谷 年洋‡,
楠本 真二† ,井上 克郎†
†大阪大学 大学院情報科学研究科
‡ 科学技術振興機構 さきがけ
{t-isio, kamiya, kusumoto, inoue}@ist.osaka-u.ac.jp
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
1
概要
表明とは
アスペクト指向プログラミング
アスペクトを用いた表明の記述
今後の課題
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
2
表明とは
表明(assertion)
特定の言語要素が「何をするのか」
その言語要素が実行される時点で(または直後に)
成立していなくてはならない条件
実現方法とは無関係
例: 「sort 関数の終了時,配列の中身は昇順で整列」
「この関数は quick sort を使う」とは書かない
対応する実行時点ごとに異なる呼び名
メソッド実行の前後: 事前条件,事後条件
すべてのメソッドの実行前後: クラス不変条件
ループ文実行中: ループ不変条件
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
3
表明の用途
早期の故障検出
表明の違反=プログラムが想定外の状態である
障害が他の場所に波及する前に検出する
障害範囲の切り分けによる原因の早期解明
責任の分担
ある一定範囲を表明で区切って責任を分担
曖昧さのない分担が可能
契約による設計
手続きの事前条件を満たすのは利用側の責任
手続きの事後条件を満たすのは手続き側の責任
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
4
利用可能な記述手段
表明文 (assert 文)
条件検査を行うプログラム文
assert(条件式);
条件式 = true なら何もしない, false ならプログラム停止
Java や C++ など,一般的な言語で利用可能
事前条件,事後条件,クラス不変条件
Eiffel ではすべてサポート
Java,C++ では JML, Larch などの支援ツール
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
5
表明を用いる際の問題
安全性と再利用性のバランス
表明として記述できる範囲の制限
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
6
安全性と再利用性
表明は安全性を高める
安全のためには書きたい
条件を書きすぎてしまうと再利用しにくい
コンポーネントの2種類の制約
コンポーネント本来の制約
例: このList には「任意の null でないオブジェクトを格納する」
一般的なオブジェクトに適用できるので,再利用が容易
アプリケーションが必要とする「最小限の」機能
例: このListには「長さ1以上の文字列を格納する」
誤ったオブジェクトを格納する可能性はなくなる
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
7
「安全な再利用」のための制限
Behavioral Subtyping
あるオブジェクトが,別のオブジェクトの代替となる条件
Strong
(拡張ではない)
Original
Component
require
(事前条件)
Weak
Specialized
Implementation
Simple
Implementation
Weak
Extension
Behavioral Subtyping
Generalization
ensure (事後条件)
Strong
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
8
アプリケーション制約の分離
アプリケーション制約とコンポーネントの制約を分離
アプリケーションの制約を後から追加できるようにする
既存の手法
総称型 (generics) : 型に対する制約 (C++, Eiffel)
部分範囲型 : 値の範囲を制限する (Pascalなど)
アスペクトによる制約の分離
アスペクトの追加,削除によって制約を管理
汎用的なコンポーネント定義+アスペクトによる表明
汎用的なコンポーネントの再利用性を損なわない
コンテキストに応じた安全性を付加する
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
9
表明が記述できる範囲の制限
表明で言及できるもの
その言語要素から可視である範囲
assert 文が記述されているメソッドのローカル変数
そのオブジェクト自身のフィールド
所有しているオブジェクトの公開フィールド
表明で言及できないもの
その言語要素から不可視の範囲
assert 文が記述されているメソッドを呼び出したオブジェクト
所有しているオブジェクトの非公開フィールド
言及できないものは通常コメントなどとして記述される
例: 「メソッドXは,メソッドYの作業用で,Yからのみ使用する」
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
10
表明で記述したいもの
複数のオブジェクトを横断した表明
一連の相互作用の事前条件・事後条件
例: ファイルから読み込まれた一連のオブジェクト群の状態
メソッドを呼び出すオブジェクトに対する条件
例: ラッパーオブジェクト以外からのアクセスを禁止する
– Façade デザインパターンなどで起こる
複数のオブジェクトに対して記述を行う場合:
カプセル化が破壊される
モジュール間の依存関係が増加する
1. アスペクトとしてオブジェクトとは別個に記述する
2. 制御フローに対する記述を可能とする
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
11
アスペクトを用いた表明の記述
アプリケーションと,コンポーネントの制約を分離したい
複数のオブジェクトを横断した制約を記述したい
 アスペクトとして表明をオブジェクトから分離する
呼び出し側に関する表明を記述したい
 制御フローに関する表明の記述方法を追加する
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
12
アスペクト指向プログラミング
目的:モジュールを横断した関心事を別モジュールに分離
AspectJ が用いる実現手段: Join Point Model
ある実行時点 (join point) に処理(advice)を連動させる
メソッド呼び出し,メソッド実行,フィールド参照,フィールド代入,例外送出
連動した advice は,その実行時点の情報にアクセスできる
例: 「String クラスへのメソッド呼び出し」の直前に,そのメソッド名
を記録する
aspect LoggingStringAccess {
before(): call (* String.*(..)) {
Logger.logs(thisJoinPoint.getSignature());
}
実行時点情報
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
13
アスペクトとしての表明の記述方法
表明=プログラムの特定の実行時点で,条件を検査する
assert 文を,開発者が自由に配置できる Join Point と考える
現在の AspectJ などでは,直接的に表現できない
表明文(assert文) の記述方法だけを拡張
事前条件および事後条件は既存の言語要素で記述
例: AspectJ を用いた事前条件および事後条件の記述
before(): メソッド実行時 {
assert (条件式);
}
after(): メソッド実行時 {
assert (条件式);
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
14
表明の記述方法の拡張
表明の宣言に用いる関数と実装を分離する
assert ( FileIsOpened(f) ); // 文の書き方は同じ
// 定義はアスペクト側に記述する
ASSERT FileIsValid(File f) {
return f.exists(); // boolean 値を返す
}
// 本体の定義は複数あってもよい: 複数ある場合は AND をとる
ASSERT FIleIsValid(File f) {
return f.canWrite();
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
15
制御フローに関する表明
AspectJ における cflow pointcut を論理式用に用いる
cflow ( object.method )
指定された object のメソッド method が実行中(呼び出しスタック
上に存在している)なら true を返す
クラスで指定された場合はそのクラスの任意のインスタンスが対象
例: writeFile 処理のときのみ,指定ファイルが書き込み可
能であることを前提とする
ASSERT FileIsValid(File f) {
return !cflow(DB.writeFile())||f.canWrite();
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
16
表明記述の AspectJ 記述との比較
提案手法による記述例
ASSERT FileIsValid(File f) {
return ! cflow ( DB.writeFile() ) || f.canWrite();
}
AspectJ で記述した例
pointcut FileIsValid_for_WriteFile (File f):
cflow(execution(void DB.writeFile())) && args(f) &&
execution(boolean AssertionAspect.FileIsValid(File));
Object around FileIsValid (File f):
FileIsValid_for_WriteFile(f) {
Boolean b = (Boolean)proceed(f)).booleanValue();
return f.canWrite() && b;
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
17
提案手法の利点
表明をアスペクトとして記述する
アプリケーションに応じた表明の追加が可能
安全性の向上
再利用性の阻害を抑えられる
コンテキストに応じた表明の記述
cflow の使用
表明の文そのものはプログラム文として通常の記述
いつ実行されるかは明瞭(「何を実行するか」だけを分離)
– 理解容易性への影響は少ない
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
18
研究の現状
提案した言語要素に対するプリプロセッサの開発中
提案言語  AspectJ コード生成
現在の課題
表明の持つ副作用
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
19
副作用の問題
表明が副作用を持つと,理解容易性が低下する
例: 配列がソート済みでないならソートする
ASSERT isSorted(Array array) {
if (! testSorted(array)) Arrays.sort(array);
return true;
}
利用者側のコード例:
array = getArray_Not_Sorted();
// 整列していない配列を受け取る
assert ( isSorted ( array ));
// ここで停止するはず
doSomethingUsingSortedArray( array );
表明関数自体が副作用を持つ場合以外にも,
他のアスペクトの作用で副作用が発生する場合もある
C++ における const のような「副作用がない」ことを言明する記述を
用いた安全性の向上が重要
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
20
まとめと今後の課題
表明の利点と弱点
故障の早期検出,責任分担
表明が記述できる範囲には制限がある
アスペクトを用いた表明の記述
横断的な表明の記述が可能になる
アプリケーション依存の制約を分離できる
今後の課題
提案する言語要素の洗練
プリプロセッサ形式による言語の実装
適用実験
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
21
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
22
既存手法との差異
“判定用関数” との違い
後から表明を追加可能
cflow による違い
AspectJ による実装との違い
アドバイスは任意の位置に書けるわけではない
複数ある場合は(自動で) AND をとる
→ 開発者が記述する手間を省略
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
23
例題
表計算プログラム
Sheet は Cell の集合を管理
Expression は Sheet 上の他の Cell を参照する
Sheet
has-a
Empty
Cell
Expression
Count
IntValue
Sum
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
24
例題に対する表明
Expression が参照している Sheet は,
Expression 自身を含んでいる.
後から別のSheet を登録
Sheet
Expression 生成
Sheet 登録
Expression
参照範囲を要求
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
25
Observer/Subject による表明検査
FileIsValidAssertion オブジェクト
検査関数を実装したものを add していく
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
26
表明の記述例
提案手法による記述例
ASSERT FileIsValid(File f) {
return ! cflow ( DB.writeFile() ) || f.canWrite();
}
AspectJ で記述した例
pointcut FileIsValid_for_WriteFile (File f):
cflow(DB.writeFile()) && args(f) &&
execution(boolean AssertionAspect.FileIsValid(File));
Object around FileIsValid (File f): FileIsValid_for_WriteFile(f) {
boolean b = (Boolean) proceed(f);
return f.canWrite() && b;
}
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
27