昨日に引き続きAOPネタ。
AspectJスタイルのAOPだと、ジョインポイント(join point)とポイントカット(pointcut)っていう概念が重要になります。でも、この用語法(ネーミング)はどうなの? 英語の語感としては自然なのでしょうか? それは僕にはわからないのだけど、個人的には違和感ありまくりです。
ジョインポイントは、主要なプログラムの流れにアドバイスコード(の実行)が“合流する点”という意味なんでしょうが、合流というよりは分岐している、割り込みが入っているという感じです。そして、“ポイント”というけど、実際には時点ではなくて時区間ですよね。フックタイミングとかのほうが僕はイメージ湧くなぁ。
それで、プログラムPに対してジョインポイント(僕ならフックタイミングと呼びたい)の集合JoinPoint(P)が定まるわけです。集合JoinPoint(P)の部分集合が、外延的にみたポイントカットですね。JoinPoint(P)は、可能性の集合ですから、実際のプログラム実行において、JoinPoint(P)のすべてのジョインポイントが実際に生起するとは限りません。
JoinPoint(P)の部分集合は、実際には論理式を使って指定します。A = {x∈JoinPoint(P) | xに関する条件(論理式)} という形式(内包的定義というやつ)で部分集合Aを指定するわけ。AspectJの構文だと、条件となる論理式のほうをポイントカットと呼んでいるように思えます。
pointcut foobar() : call(* *.foo(..)) || call(* *.bar(..));
この例だと、プリミティブ・ポイントカットcall()が組み込み述語みたいなもので、論理記号(結合子)「||」で複合した論理式にfoobarという名前を付けていることになります。だから、foobarはユーザー定義述語ですね(fooまたはbarという名前のメソッドが呼ばれるタイミングを定義する述語)。
どうでもいいけど、ポイントカットって、ポイントをカットするの? それ以上切り分けることができない存在物をポイント(点)と呼ぶんじゃなかったかな、…違和感。
それはそうとして、アスペクトのコードは、if-then-do、あるいはパターン・アクションの形式になります。if (あるタイミングに遭遇したら) then {ある動作をする}
ここで、doのところをアドバイスと呼んでいるんです。ifの部分(またはパターンの部分)のタイミングが、ポイントカットで記述される、と。
もう少し正確に言うと、A⊆JoinPoint(P) というジョインポイント集合(ポイントカット論理式に対応する部分集合)があるとき、before A は、Aに属するタイミングt(実行時の時区間)の直前の時点の集合です。AspectJのbefore() : α {/* アドバイス */}
(αはAを記述する論理式)は、{before t | t∈A} という時点集合のそれぞれに対して、アドバイスコードの呼び出しを割り当てる指令になっています。afterも同じ。aroundのときは、タイミング(時区間)を一点(時点)につぶして考える。
と、まー、僕はこういうふうに解釈して、一定の納得を得たのですが、曲解かもしれません。それでも、ポイントカットに対して、“実行時の(可能性としての)全タイミング集合の部分集合を、(述語論理の)論理式で定義する”という観点(aspectってか)を持ったほうがいいと思いますね。