Pointcut Overriding

どうやってポイントカットの定義を拡張する?


たとえば、以下のようなコードがあったとして:


public aspect MyAspect {

pointcut mypc() : call( (MyClassA || MyClassB).myMethod() );

}

MyClassA と MyClassB に加えて、MyClassC を追加したいとしたら? 最も直接的な方法は:

public aspect MyAspect {

pointcut mypc() : call( (MyClassA || MyClassB || MyClassC).myMethod() );

}

しかし、MyClassC は、一時的に必要なだけとしたら? そういうときには、オーバーライドできると便利かも:

public aspect MyAspectExtenstion {

pointcut override MyAspect.mypc() :
TypePattern || MyClassC;
}

ここで TypePattern は MyClassA || MyClassB を表しているつもり。もちろん、現実的には、こういうふうには、うまくできない。たとえば、call pointcut は複数あるかもしれない:

public aspect MyAspect {

pointcut mypc() :
call( (MyClassA || MyClassB).myMethod() ) ||
call( (MyClassA || MyClassB).myMethod2() );
}

そういう場合には、どっちの TypePattern を表しているのかが不明になってしまう。


その他の問題点は、どれが拡張するポイントカットを使用するのか、という点。ポイントカットをオーバーライドするアスペクトは、複数あるかもしれない:


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;
}

とかでできる(と思う。コンパイルしてないから間違ってるかもしれないけど)。


でも、インタフェースを使う方法は、ややめんどっちい雰囲気もある。