アスペクトを用いた表明の記述 石尾 隆†,神谷 年洋‡, 楠本 真二† ,井上 克郎† †大阪大学 大学院情報科学研究科 ‡ 科学技術振興機構 さきがけ {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
© Copyright 2024 ExpyDoc