Pointcut Overriding
どうやってポイントカットの定義を拡張する?
たとえば、以下のようなコードがあったとして:
MyClassA と MyClassB に加えて、MyClassC を追加したいとしたら? 最も直接的な方法は:
public aspect MyAspect {pointcut mypc() : call( (MyClassA || MyClassB).myMethod() );
}
しかし、MyClassC は、一時的に必要なだけとしたら? そういうときには、オーバーライドできると便利かも:
public aspect MyAspect {pointcut mypc() : call( (MyClassA || MyClassB || MyClassC).myMethod() );
}
ここで TypePattern は MyClassA || MyClassB を表しているつもり。もちろん、現実的には、こういうふうには、うまくできない。たとえば、call pointcut は複数あるかもしれない:
public aspect MyAspectExtenstion {pointcut override MyAspect.mypc() :
TypePattern || MyClassC;
}
そういう場合には、どっちの TypePattern を表しているのかが不明になってしまう。
public aspect MyAspect {pointcut mypc() :
call( (MyClassA || MyClassB).myMethod() ) ||
call( (MyClassA || MyClassB).myMethod2() );
}
その他の問題点は、どれが拡張するポイントカットを使用するのか、という点。ポイントカットをオーバーライドするアスペクトは、複数あるかもしれない:
public aspect MyAspectExtenstion2 {pointcut override MyAspect.mypc() :
TypePattern || MyClassC || MyClassD;
}
ソースが手に入るときは、最初に見たような直接編集するやりかたが、ベターかもしれないけど、ソースが編集できない場合は、ポイントカットの拡張性の問題になるかもしれない。
拡張される側がそのような拡張に対処する方法の一つは、直接クラスを「||(or)」でつなぐのではなく、インタフェースなどを通して行う方法が考えられる:
拡張する側は:
public aspect MyAspect {public interface MyInterface {
public void myMethod();
}declare parents: MyClassA implements MyInterface;
declare parents: MyClassB implements MyInterface;pointcut mypc() : call( MyInterface.myMethod() );
}
とかでできる(と思う。コンパイルしてないから間違ってるかもしれないけど)。
public aspect MyAspectExtenstion {
declare parents: MyClassC implements MyAspect.MyInterface;
}
でも、インタフェースを使う方法は、ややめんどっちい雰囲気もある。