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

実行結果はさっきと同じ。

何がいいたいのかっていうと、オブジェクト指向では、同じ階層に属するってのがコンパイラに基本的には要求される:


Shape s1 = new Point(); // ok
Shape s2 = new Person(); // no
このような型要求は、現在の Aspectual Polymorphism にはないような気がする。
問題は、このような要求はなくてもよいのか、それとも、あるほうがいいけど、まだ 実現されていないだけのか、ということ。


もう一つは、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

なんの違和感もない?