Aspectual Polymorphism
まだまだマイナな単語だと思うけど「Aspectual Polymorphism」についての覚書(なので or なのだけど、読者を限定した書き方になってしまうかも&用語とか適当に使う)。いつかどこかにちゃんとした形でまとめるかもしれないけど。
"Polymorphism" という用語から分かるように、オブジェクト指向におけるポリモーフィズムと同じような感じに、アスペクト指向における、ポリモーフィズムとはなんでしょう、という話。
これは比較的新しい話題なので「Aspectual Polymorphism って何?」という話ではなく「Aspectual Polymorphismとは何であるべきか? 何を Aspectual Polymorphism と呼べば良いのか?」という話。
Aspectual Polymorphism はAOP 言語の一つである Caesar の文脈でいえば「オブジェクトの振る舞いは、通常のポリモーフィズムだけで実行時に決定されるのでなく、そこに処理が移った時点で、どのアスペクトがデプロイされているかにも依存する」というニュアンス(だと思う)。
たとえば、以下のような Caesar のコードがあるとして:
public cclass SimpleLogging {
before() :
call( void Point.setX(int) ) || call( void Point.setY(int) )
{
System.out.println("SimpleLogging before setX");
}
}public cclass VerboseLogging extends SimpleLogging {
before() : call( void Point.setColor(String) ) {
System.out.println("VerboseLogging before setColor");
}
}public class Main {
public static void main(String[] args) {
run("");
run("verbose");
}
private static void run(String mode) {
System.out.println("mode: " + mode);SimpleLogging logger;
if ( mode.equals("verbose") ) {
logger = new VerboseLogging();} else {
logger = new SimpleLogging();
}
deploy( logger ) {
Point p = new Point(1, 2);
p.setX(10);
p.setY(20);
p.setColor("red");
}
}
}
実行結果は以下のようになる:
mode:
SimpleLogging before setX
SimpleLogging before setX
mode: verbose
SimpleLogging before setX
SimpleLogging before setX
VerboseLogging before setColor
つまり、deploy に渡されたアスペクトインスタンスによって deploy 内の振る舞いがかわる。現在いわれている Aspectual Polymorphism っていうのはこういう雰囲気。
でも、Aspectual Polymorphism であることの条件ってなに?
たとえば、SimpleLogging と VerboseLogging が同じクラス階層に属していなくても、Aspectual Polymorphism と呼んでも良いのか?
public cclass SimpleLogging {
before() :
call( void Point.setX(int) ) || call( void Point.setY(int) )
{
System.out.println("SimpleLogging before setX");
}
}public cclass VerboseLogging {
before() :
call( void Point.setX(int) ) || call( void Point.setY(int) )
{
System.out.println("VerboseLogging before setX");
}
before() : call( void Point.setColor(String) ) {
System.out.println("VerboseLogging before setColor");
}
}public class Main {
public static void main(String[] args) {
run("");
run("verbose");
}
private static void run(String mode) {
System.out.println("mode: " + mode);
Object logger;
if ( mode.equals("verbose") ) {
logger = new VerboseLogging();} else {
logger = new SimpleLogging();
}
deploy( logger ) {
Point p = new Point(1, 2);p.setX(10);
p.setY(20);
p.setColor("red");
}
}
}
実行結果はさっきと同じ。
何がいいたいのかっていうと、オブジェクト指向では、同じ階層に属するってのがコンパイラに基本的には要求される:
このような型要求は、現在の Aspectual Polymorphism にはないような気がする。
Shape s1 = new Point(); // ok
Shape s2 = new Person(); // no
問題は、このような要求はなくてもよいのか、それとも、あるほうがいいけど、まだ 実現されていないだけのか、ということ。
もう一つは、deploy 外でデプロイされているアスペクトの存在。
public class Main {public static void main(String[] args) {
DeploySupport.deployBlock( new SimpleLogging() );
run("");
run("verbose");
}
private static void run(String mode) { // 変更なし
System.out.println("mode: " + mode);
Object logger;
if ( mode.equals("verbose") ) {
logger = new VerboseLogging();} else {
logger = new SimpleLogging();
}
deploy( logger ) {
Point p = new Point(1, 2);p.setX(10);
p.setY(20);
p.setColor("red");
}
}
}
実行結果は:
mode:
SimpleLogging before setX
SimpleLogging before setX
SimpleLogging before setX
SimpleLogging before setX
mode: verbose
VerboseLogging before setX
SimpleLogging before setX
VerboseLogging before setX
SimpleLogging before setX
VerboseLogging before setColor
なんの違和感もない?