空想犬猫記

※当日記では、犬も猫も空想も扱っておりません。(旧・エト記)

Double Dispatch (Visitor pattern) に関する考察 (4)

id:xoinu:20070629,id:xoinu:20070630,id:xoinu:20070701 で長々とみてきた Double Dispatch の(Visitor パターン)みそは,結局何なのか?もっと的確な言葉が見つかった。

  • 元のクラス(群)をいじらずに,仮想関数を追加できる
  • しかも,仮想関数のスコープを,より柔軟に制御できる

ということだろう。この見方ができるようになると,C++でソフトウェアをデザインする際に,選択の幅が広がる。

1つ目は,今までのやってきたことを言い換えただけ。型判別の switch 文の変わりになるということは,仮想関数の代わりになるということ。2つ目は,Dispatcher のスコープを関数内,ファイルスコープ,その他の名前空間など,つまりコード中のどこにでも置けるということを言い換えただけだ。

仮想関数追加によるクラスの拡張を縦方向の拡張だとしたら,Double Dispatch による機能の追加は横方向の拡張だといえるだろう。Double Dispatch の機能をクラスに追加するだけで,拡張の方向が,1次元から2次元にレベルアップするようなイメージだろうか。何がすごいのか,言葉にできなくてもやもやしてみたものが,言葉にできてよかった。

絵にするとこんな感じ
http://farm2.static.flickr.com/1382/700635427_02c3d50e60_o.png
縦方向が,クラスの機能だとしよう。楕円のひとつひとつが,それぞれのクラスの実装だとすると,メンバ関数を追加するのは,縦長の楕円を縦に延ばすイメージ。クラスの機能を追加するには,4つの縦長の楕円をいじる必要がある。それに対して,Double Dispatch の場合は,必要に応じて,新しいクラスをひとつ追加するだけで良い。メンバ関数の追加はそのクラスを利用する全てのコードに影響を与えるのに対し,Dispatcher のスコープは実装者が自由に選ぶことができる。
・・・あ,いまさらながらに「データと処理を分離する」の言いたいことが分かった(笑)。しかし,正確に言えば「データと処理を分離するためにも使える」だろう。分離するかどうかはクラスの設計次第だ。新しい機能を dispatcher で実現するか,メンバ関数の追加で実現するかは,その時々の状況次第ってこと。