「アスペクト指向入門 -Java ・ オブジェクト指向から AspectJプログラミングへ」を読んだので
javascriptでAOPするaspect.jsというのを考えてみた。
方針はこんな感じ。
- advice(aspectで実行されるコード本体、という説明で合ってるのかな)は普通の関数として定義する
- weaving(aspectの合成)は動的に実行する
マクロ展開レベルのcode generatorを作ってもいいけど、javascriptらしくないよね - 使用できるjoinpoint(adviceを注入できる場所というか時というか)は、関数の実行(execute)のみ
クラスフィールド関連のjoinpointは不要だし、変数の参照・代入をどうにかするのは無理っぽい
とりあえず、関数呼び出しのaround advice(joinpointの前後に実行されるadvice)が書ければ、後はなんとでもなりそうなので、その方法を考える。
例えば、Fooオブジェクトのbar()関数(Foo.bar())があるとして、これにaround adviceを追加するには、
Foo.original_bar = Foo.bar;
Foo.bar = function() { // この名前なし関数全体がaround advice
// ここがbefore相当
Foo.original_bar.apply(this, arguments);
// ここがafter相当
}
といった感じで実装できる。汎用的にやるには色々と手間が必要だけど、まぁなんとかなりそうだ。
次にpointcut(joinpointの集合)を指定する方法だけど、for (var key in object) {}してやればオブジェクトが持っている関数名を文字列として取得できるので、後は正規表現かなにかでmatchingさせればいい。オブジェクトさえ指定されていればweavingにそれほど時間がかからず、あまりパフォーマンスが落ちない形で実装できると思う。
問題は、任意のオブジェクトにのある関数、というpointcutの指定をどう処理するかである。
AspectJで言えば、call(*.set*())みたいなのは、動的にやるのが厳しい。ここまで極端な例はあまり使わないかも知れないが、call(*Widget.initialize())程度の指定ならありそうで、かつ全く同じ問題があるので、なんとかしないといけない。
原理的には、rootとなるオブジェクト(windowとか)から全てのオブジェクトに到達可能なので、指定自体は可能である。
が、オブジェクト数が多い場合、この方法ではweavingに時間がかかりすぎて実用的なパフォーマンスが出ないような気がする。
ここだけ静的に処理します、というのも格好悪いしなぁ。う~ん。
ちなみに、「アスペクト指向入門」はこれ↓
http://www.amazon.co.jp/exec/obidos/ASIN/4774125814/
読みやすいのでお勧め。
- Category(s)
- ユーザーインターフェース
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/anaka/300c30a230b930af30c86307541151659580-java-30fb-30aa30a730af30c863075411304b3089-aspectj30ed30e930df30f33078300d30928aad3093306e/tbping