Entry

ActionMapping クラスっぽいことを C++ でやってみる

2008年08月24日

C++ で Struts みたいなことをやってみよう企画。地味に続いています。今回は ActionMapping みたいなことをしてみよう!です。

Struts の ActionMapping は,FrontController パターンで一括して受理したリクエストを,各 Action クラスに振り分ける作業をします。具体的には,HttpServletRequest オブジェクトと事前に定義した XML ファイルを突き合わせて,投げ先のコントローラ(Action)を決定します(※Action クラスは Model だろ,というウワサもあるんですけど,コントローラとして考えた方が都合がいいので,コントローラとしておきます)。

で,このマッピングの作業なんですけど,要するに,文字列をキーにして,それに対応するオブジェクトを作ることが目的だったりします。この点,Java の場合は,あまり細かいことを考えなくても,リフレクションを使えば簡単に文字列からオブジェクトを作ることができちゃうんですけれど,C++ ではなかなか難しい。RTTI なことはそれなりにできるけれど,メタプログラミングって,そもそもあまり得意じゃないんですよね……。

ためしに C++ で forName() してる方がいるか調べたところ,奥さんのところで API にしてらっしゃるみたい。あたしのは,正確にはリフレクションじゃなくて,文字列から Action を引っ張るモンなんですけど,こんな感じで作ってみました(コードが割と長くなっちゃったので,クラス図にしておきます)。

ActionMapping を書いてみるのクラス図

えとですね。まず,ActionMapper という抽象クラスを継承して自分用の ActionMapper(図中 SomeActionMapper)を作ります。で,このクラスに defineActionMap() を実装します。ここで何を実装するかというと,インスタンスメソッドである,set*Handler() を呼ぶこと。set*Handler() は,名前(文字列)とインスタンスの作成/実行/削除用のハンドラを引数に取って,名前に対してする処理を登録することができます。言ってみれば,名前とオブジェクト操作を対応付ける箇所なわけで,Struts でやるところの XML ファイルに定義することと同じことを,ここでやるというわけです。

この点,なんで Struts のように XML で定義しないのかというと,ここで考えているフレームワークが CGI 用だからです。XML に定義を移せば,作る側からは作りやすくなるんですけれど,CGI ですから,起動する度に XML ファイルをパースしなくちゃいけなくなりますよね。二次記憶(HDD)から読むだけでもそれなりにオーバーヘッドがかかるのに,XML の解析もするとなると,アワワなことになってしまいます。名前とクラスの対応付けってのは,開発中ならともかく,運用に乗ったら動的にどうこうするもんじゃないわけで,それくらいコーディングしなさいな,ということにしたのでした。定義を変えたら,コンパイルし直しってのはあるんですが。

ハンドラの定義は,図にも書いてあるけど,こんな感じ。

    typedef Action* (ActionMapper::*ActionCreateHandler)();
    typedef bool (ActionMapper::*ActionExecuteHandler)();
    typedef void (ActionMapper::*ActionDeleteHandler)();

名前とハンドラは std::map として STL の map で管理されます。管理の中に入れたハンドラは,もちろん定義されていないといけないので,継承した SomeActionMapper クラスに実装します。あとは,execute() を名前付きで呼べば,所望の Action を作って,execute() メソッドを呼んでくれます。

ここで ActionMapper に execute() だけを実装したのは,ActionCreateHandler() の戻り値(new した SomeAction オブジェクトへのポインタ)なんかを公開すると,勝手に delete されそうでこわいからです。SomeAction オブジェクト自体は ActionMapper 内にラップしておいて,比較的安全なトリガである execute() インターフェイスだけを公開しておく,という寸法です。

ざっと作ったところ,デザパタが入り組んでいるんので(Facade/Proxy + Factory か?),まだちと冗長なところがあったりします。登録するするハンドラも,似たようなものがあふれそうだし(new してポインタを返すだけ,とか)。クラスを分ければもちっとシンプルになりそうな感じがします。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN