AspectJ デザインパターンの Worker Object Creation というのをやってみる。
下のコードを実行すると、コンソールに1,2,3 と順番に表示されるが、これを3,2,1 と逆順で実行されるようにしてみる。本番の開発では、そんなことしないだろうけど、実験として試してみたい。
public class App {
void foo() {
bar(1);
bar(2);
bar(3);
}
void bar(int number) {
System.out.println(number);
}
public static void main(String[] args) {
new App().foo();
}
}
AspectJ In Action (古い版)に Worker Object Creation という技が載っていて、メソッド呼び出しをオブジェクトにくるんで管理したり間接的に実行するパターンが、そう呼ばれている。これを応用すると以下のようなアスペクト定義で、たとえば上のような逆に実行すといった制御も実現できる。
public aspect Reverse {
static interface Worker { void run(); }
Stack<Worker> history = null;
pointcut callFoo(): execution(void App.foo());
pointcut callBar(): execution(void App.bar(int));
before (): callFoo() {
history = new Stack<Worker>();
}
after (): callFoo() {
while (!history.empty()) history.pop().run();
}
void around(): callBar() {
history.push(new Worker(){
public void run() { proceed(); }
});
}
}
動かしてみると、bar() 呼び出しが逆順に実行され、コンソールに 3,2,1 と表示される。
AspectJ In Action のサンプルコードでは、メソッド呼び出しを Runnable.run()からproceed() して非同期にしている。また同書10章「Authentication and Authorization」の、PrivilegedExceptionAction.run() からproceed() しているイディオムも、worker object creation の一例。おそらくこういった別スレッド化やセキュリティ対応などといったアスペクトが、このパターンの典型的な使い型だろうけど、やればこんな変な事もできるというのを試してみた。
0 件のコメント:
コメントを投稿