【デザインパターン】Visitor

どういうもの?

  • 既存オブジェクトに対する新たな操作を、構造を変化させずに追加できる
  • classic technique for recovering lost type information
  • ダブルディスパッチを利用

どんなときに使う?

  • あるクラスに機能追加するときに、構造を変化させたくないとき

構成要素

  • Element
  • ConcreteElement
  • Visitor
  • ConcreteVisitor
  • Client

コード

  • elementを継承したクラスにaccept(visitor)の実装を書く
  • visitorという基本クラスを作り、それぞれのelementタイプに対してメンバ関数を作る
  • visitorのサブクラス(ConcreteVisitor)を作り、メンバ関数を継承する
  • Clientが、visitorオブジェクトを作り、それらをaccept()に渡す。
#include <iostream>
using namespace std;

class ConcreteElement;

class Visitor{
public:
  virtual void visit(ConcreteElement *Object) = 0;
};

class ConcreteVisitor: public Visitor{
public:
  ConcreteVisitor()
  {
  }
  void visit(ConcreteElement *Object){
    cout << "visit() at ConcreteVisitor" << endl;
  }
};

class Element{
public:
  virtual void accept(Visitor* Object) = 0;
};

class ConcreteElement: public Element{
public:
  void accept(Visitor* Object){
    Object->visit(this);
  }
  void print(){
    cout << "print() at ConcreteElement" << endl;
  }
};


int main(){
  ConcreteElement e;
  ConcreteVisitor v;
  e.accept(&v);
  e.print();
}