複数個のJoinpointの集合を
対象としたPointcutを
記述可能なアスペクト指向言語
理学部 情報科学科
指導教官 千葉 滋 助教授
学籍番号 01_14577 竹内 秀行
異なるクラス階層を持つ変更
既存のソフトウェアに新しい役割を持たせる
オブジェクト指向で設計すると階層構造が破綻
別々に記述できたほうが開発しやすい
人材管理モジュール
給与台帳モジュール
社員
社員
平社員
調査担当
販売担当
管理職
調査担当部長
販売担当部長
調査部
調査担当
調査担当部長
販売部
販売担当
販売担当部長
クラスの合成
人材管理::販売担当
社員管理::販売担当
給与台帳::販売担当
名前()
部下()
表示()
表示()
表示()
部下()
給料()
表示()
名前()
給料()
名前()
同じ対象を表現するクラス同士を合成する
それぞれのクラスが持つすべてのメソッドおよびフィールド
を一つのクラスから利用できるように
メソッド名が衝突した場合のルールは別に記述
既存のアスペクト指向言語
AspectJ[Kiczalesら’01]
現在最も一般的なアスペクト指向言語
特徴点 (joinpoint) を探し出しコードを挿入
メソッド呼び出しやフィールドアクセス等
Pointcut
Joinpointを抽出するための記述
call(void System.out.println(..)) && within(Logger)
Advice
Joinpointの新しい振る舞いをJavaコードで定義
before() : log() { System.out.println(“[” + now() + “] ”); }
AspectJによるクラス階層の合成
AspectJでの方針
クラス階層を別々に開発
インスタンス化時に関連付け
メソッド呼び出し等をpointcut
AspectJの問題点
pointcut で単一の joinpoint しか抽出できない
リフレクションを利用しなければならない
一方向にしか関連付けることができない
単一のJoinpointの制限①
人材管理
給与台帳
調査担当 Aspect
販売担当 Aspect
販売担当
調査担当
インスタンス化時にClass.forName()で
探してバインド
インスタンス化を pointcut し、リフレクションで関連付け
実行速度の低下
単一のJoinpointの制限②
人材管理::販売担当
表示()
部下()
Aspect
名前()
給与台帳::販売担当
表示()
給料()
名前()
一方向にしか関連付けることができない
基となるモジュールをあらかじめ決める必要がある
逆方向の参照はオブジェクト同士のマッピングが必要
提案:複数個のJoinpointの集合を
選択できるPointcutの記述
pointcut に連結演算子(##)を導入
pointcut式 ## pointcut式
左右の式で得られるjoinpoint集合の配列を連結
従来の pointcut式の結果 は要素1の配列として扱う
利用例
人材管理パッケージのクラスと給与台帳パッケー
ジのクラスを抽出
class(personnel.*) ## class(payroll.*)
Jugglingクラスのstart()とend()の呼び出しを抽出
call(Juggling.start ()) ## call(Juggling.end ())
クラス階層の合成
composition advice の導入
複数のクラスを Joinpoint としてとる
Hyper/J[Ossherら’00]の記述を応用
composition() :
class(personnel.*) ## class(payroll.*) {
mergeByName;
override String $2.name()
with String $1.name();
String $composed.toString() {
StringBuffer ret = new StringBuffer();
for (int i = 0; i < $result.length; ++i)
ret.append($result[i]);
return ret.toString();
}
}
Composition Advice
mergeByName;
何も指定されなければ同じ名前のメソッドを結合
結合後のメソッドは合成前のクラスのメソッドを順番に呼び
出し最後の呼び出しの結果を返り値とする
override String $2.name() with String $1.name();
name()メソッドは結合せずに二番目のjoinpointのメソッド
を呼び出す
$1,$2はpointcutによって得られたjoinpoint配列の要素
String $composed.toString() { … }
結合されたtoString()の返り値を再構成する
実装
拡張可能なコンパイラ
pointcut および advice を Java で追加可能
Polyglot, Javassistを用いて作成
コンパイル速度の比較
PureTLS Toolkits のコンパイルおよび合成
クラス数: 127個 行数: 約18000行
joinpoint: 6384個 うち合成対象箇所: のべ1052個
単位はms
juggler
javac1.5
ajc1.2
abc1.0
Aspect無し
18601
2972
4443
23101*
Aspect有り
19019
5317
N/A
*内部エラーにより終了(バイトコード変換で問題発生)
関連研究
Hyper/J
異なるモジュールの合成を行うアスペクト指向シ
ステム
メソッド、フィールド、クラスを既存のモジュールか
ら切り出し他のモジュールに合成を行う
自由度が高い反面、ユーザーが面倒を見なけれ
ばならないところが多い
まとめ
複数個のJoinpointの集合
pointcut式に連結演算子を導入
composition adviceによるクラス階層の合成
今後の課題
pointcut による記述の柔軟性を生かし切れていない
advice での joinpointの扱いの整合性がとれていな
い
他の複数の joinpoint を必要とするアスペクトの記述
おしまい
質問用スライドに続く…
単一のJoinpointの限界③
人材管理::販売担当
名前()
表示()
役職()
性別()
Aspect
解雇()
給与台帳::販売担当
役職()
性別()
表示()
解雇()
備考()
名前()
備考()
一つ一つ記述する
メソッド・フィールドごとに一つのアドバイスが必要
保守が難しい
Hyper/Jによる解法
特徴点の抽出
package personnel : Feature.Personnel
package payroll : Feature.Payroll
その振る舞いの定義
relationships:
mergeByName;
override operation Feature.Payroll.name
with operation Feature.Personnel.name;
AspectJと何が違う?
特徴点 (Joinpoint) が二つある
AspectJ での実際のコード例
public aspect PersonnelWithPayroll perthis(this(personnel.Employee+)) {
private payroll.Employee payroll;
before(personnel.Employee personnel) :
execution(personnel.Employee+.new())
&& this(personnel) {
String name = personnel.getClass().getName();
name = nameのクラス名だけ取り出す;
payroll = Class.forName( “payroll.” +name).newInstance();
}
after(String name) :
execution(void personnel.Employee+.setName(String))
&& args(name) {
payroll.setName(name);
}
…
}
© Copyright 2026 ExpyDoc