2009年12月11日金曜日

AspectJ design pattern: Wormhole

Aspectj in Action: 第一版に載ってた、デザインパターン。
public class ClassA {
   ClassB b = new ClassB();
   void foo(int count) {
      for (int i = 0; i < count; ++i) b.bar(i);
   }
}
class ClassB {
   void bar(int i) { new ClassC().baz(i); }
}
class ClassC {
   void baz(int i) { System.out.println(i); }
}
上のコードを "new ClassA().foo(3);" のように実行すると、下図左のような出力になるが、これを下図右のように最後の1行だけ修飾したい。
0
1
2
0
1
last -> 2
このためには baz() 呼び出し時に、foo() 呼び出し時に渡された count が参照できなければならないが、bar()、baz() のシグネーチャは汚したくない。こういうときに AspectJ の Wormhole パターンが使える。 もとのコードは変えないまま、こんなアスペクトで上記の結果が得られる。
public aspect AspectX {
   pointcut foo(int count) : execution(void ClassA.foo(int)) && args(count);
   pointcut baz(int i) : execution(void ClassC.baz(int)) && args(i);
   pointcut wormhole(int count, int i): cflow(foo(count)) && baz(i);
   before(int count, int i) : wormhole(count, i) {
      if (count == i + 1) System.out.print("last -> ");
   }
}

0 件のコメント:

コメントを投稿