AOP and Attribute

kmt-t(id:kmt-t)さんよりこんなご質問を頂きました.ソフトウェア設計論も真面目に学んだことがない私がAOPの話をするのも恐縮ですが,及ばずながらお答えさせていただきたいと思います.

『はじめましてkmt-tといいます。orzEngineでつかっているAOPのテクニックって、NyaRuRuさんオリジナルのものなんでしょうか?それとも何か情報のソースがありますか?実のところ、自分はAOPdotNETの技術をキャッチアップできていない(AOPの本は買ったがまだ読めていない)んでよくわからないんですが、解説お願いできますでしょうか。ちょろっとみたところ、属性でマーキングされたメソッドをInterceptするようになっているようで、メソッド名をつかってInterceptするよりかなりスマートな感じをうけましたが、どうなんでしょうか。』

orzEngineのAOP周りにはネタ本とでも呼ぶべきものがあります.それが"Essential .NET"です.そもそもこの本の第7章が無ければ私は .NET Framework 奥底に眠る割り込み機構のドキュメントの少なさに途方に暮れていたことでしょう.
Essential .NET ― 共通言語ランタイムの本質
面白いのは,今回私が利用した技術の本質は全てEssential .NETの「1.1 COMの再考」という節に集約されていることです.この章で著者は1990年代前半のMicrosoft Transaction Server (MTS)が既に「属性」と「割り込み」にフォーカスした技術であったとしています.著者はまた,MTS が実現した属性の宣言と割り込みをベースとしたモデルがSun Microsystems の Enterprise Java Beans (EJB) でも採用されていることも指摘しています.このあたり私はJavaはあまり詳しくないので,主にMicrosoftサイドからの資料をいくつか挙げておきます.
http://www.microsoft.com/japan/com/slides/8-301.ppt
http://download.microsoft.com/download/5/f/9/5f9573a3-121e-400a-8d34-ce6d4382098e/MTS_EJB.doc
http://java.sun.com/j2ee/ja/ejb/ejbvscom.html
そして結局のところorzEngineで使用している手法はここ10年近くの時代背景を考えれば何ら新規性は無いのではないか,というのが私の結論です.以上ご参考になりましたでしょうか? いずれにせよ"Essential .NET"は一読に値する書籍だと確信しています.orzEngineで利用した割り込みポイントも,全5種 全4種*1のうちのたった1つでしかありません.そもそもorzEngineではContextBoundObjectを利用しているにもかかわらず,Contextを全く利用していないのです.Contextについては現在何とか面白い使い道はないか検討中なので,もしかしたら近いうちに何か実装例が公開できるかもしれません.


さて,以下蛇足ですが私なりの歴史の理解です.専門家の方々から見たらずいぶん嘘が混ざっているかもしれませんのでご注意下さい.
実際IDL,CORBA,OMGといった世界では,かなり以前から「属性」という概念が利用されていたようです.私もCOMオブジェクトの実装でIDLを読んだり書いたりしたことがありますから,[In]や[Out]といった記法にはなじみ深いものがあります.当時の属性の使われ方というのは,IDLというひな形からソース生成を行うための便利な記法という性質が強かったように思います.属性付きのインターフェイスをIDLに書いてコンパイルすることで,マーシャリングコードが追加されたり非同期化が施されたC++クラスのひな形が出力されるといった感じです.
http://www.microsoft.com/japan/msdn/thisWeek/combasics/combasics2.asp
COMの頃はTLB(タイプライブラリ)とIDLという2つの型情報表現が独立して存在したため,IDLで指定した属性の全てがTLBには書き込まれないという問題がありました.COMでの実行時型情報はTLBからしか得られないため,結果としてIDLに記述された属性情報はごく一部のみが実行時に参照できるだけでした.
一方,WMIで使用されるMOF Fileも属性*2が積極的に使われる例です.

CIMで得られるのはオブジェクトの厳密で完璧な定義であり、管理する環境に関して使用可能な情報をその中で取りまとめることが可能な、よく知られた概念的枠組みを提供します。CIMは、オブジェクトスキーマに対して動作するコードを記述する必要のあるプログラマや、新しい情報を管理環境の中で使用可能にしようとするスキーマ設計者によって明確に理解されるものと想定されています。CIMマネージメント情報は、マネージドオブジェクトフォーマット(Managed Object Format:MOF)と呼ばれるインタフェース定義言語(Interface Definition Language:IDL)をベースとした強力な言語で記述されます。MOFは、オブジェクト定義をテキスト形式で記述する方法の1つで、マシンで読み込んだり、インタフェーススタブコンパイラのオブジェクトマネージャをサポートすることもできます。定義を記述するための構文を設定します。MOF仕様の主要な構成要素は、テキストで記述したクラス、関連付け、プロパティ、参照、方法、インスタンス宣言と、それらに関連付けられた修飾子です。

実際以下のサイトからMOF Filesを1つダウンロードして中を覗いてみると,そこでは見慣れた属性表記が多数利用されています.
http://www.dmtf.org/standards/cim/cim_schema_v28
MOFでは属性情報もCIMリポジトリも記録されるようになったため,聞くところによると積極的な実行時属性評価と割り込み処理が行われていたようです.
http://www.microsoft.com/japan/technet/prodtechnol/windows2000serv/maintain/featusability/wmisnmp.asp
私は主に DirectX の原始的 COM コンポーネントとお遊び程度の ATL COM オブジェクトしか触っていなかったため,これらの技術進化は単なるエンタープライズ分野の政治的駆け引きと見えることもありました.年を追うごとに大がかりになっていく仕組みは,もはやアプリケーションプログラマの手に余ると感じていました.今振り返ると,この急進化現象は Keijiro Takahashi 氏が『Fire and Motion』で紹介されていた「Microsoft の攻撃的戦略」そのものだと思えます.
http://www.radiumsoftware.com/0402.html#040207
そして .NET Frameworkの時代になって,これら主にエンタープライズ分野で醸成された技術と思想がやっと趣味プログラマの手の届く領域に降りてきたと感じました.
http://www.microsoft.com/japan/msdn/net/general/entserv.asp
http://www.ascii.co.jp/pb/msdn/article/a25_0045.html
http://msdn.microsoft.com/msdnmag/issues/03/03/ContextsinNET/default.aspx
このような「一般向け」のAOP環境としては,AspectJなどでJavaがかなり先行しているように見えます.
http://japan.cnet.com/news/ent/story/0,2000047623,20065072,00.htm
ただ,.NETへと至る系譜でAOP的資産も数多く積み重ねられているのは事実でしょう.IBMほど表だってはいなくても,確実に.NETにもAOPの影響は現れてくると考えています.まあそんなわけで習作がてらに作られたのがDeviceHookなりorzEngineということですね.
http://www.dwahan.net/nyaruru/devicehook/

*1:Envoy Sink, Client Context Sink, Server Context Sink, Object Sink, Object Context Sink

*2:WMIでは修飾子と呼ばれます