행위패턴-Visitor

2008. 8. 4. 22:52 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Visitor]
의도:
객체 구조의 요소들에 수행할 오퍼레이션을 표한한 패턴이다. Visitor 패턴은
오퍼레이션이 처리할 요소의 클래스를 변경하지 않고도 새로운 오퍼레이션을
정의 할 수 있게한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Visitor
//
/////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <list>

class ElementA;
class ElementB;
class CompoisteElement;

/////////////////////////////////////////////////////////////////////////////
//
// Visitor base
//
/////////////////////////////////////////////////////////////////////////////
class Visitor
{
protected:
 Visitor();
public:
 virtual ~Visitor();

public:
 virtual void VisitElementA (ElementA *);
 virtual void VisitElementB (ElementB *);
 virtual void VisitCompoistElement(CompoisteElement *);
};

Visitor::Visitor() {}
Visitor::~Visitor() {}

void Visitor::VisitElementA (ElementA *)
{
 std::cout << "Visitor::VisitElementA (ElementA *)" << std::endl;
}

void Visitor::VisitElementB (ElementB *)
{
 std::cout << "Visitor::VisitElementB (ElementA *)" << std::endl;
}

void Visitor::VisitCompoistElement(CompoisteElement *)
{
 std::cout << "Visitor::VisitCompoistElement (ElementA *)" << std::endl;
}


/////////////////////////////////////////////////////////////////////////////
//
// Element base
//
/////////////////////////////////////////////////////////////////////////////
class Element
{
protected:
 Element ();
public:
 virtual ~Element ();

public:
 virtual void Accept (Visitor &) = 0;
};

Element::Element () {};
Element::~Element () {};


/////////////////////////////////////////////////////////////////////////////
//
// Elements
//
/////////////////////////////////////////////////////////////////////////////
class ElementA : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementA (this);
 }
};

class ElementB : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementB (this);
 }
};

class CompoisteElement : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  std::list<Element*>::iterator i;

  for (i=childs_.begin(); i!=childs_.end(); i++)
  {
   (*i)->Accept (v);
  }

  v.VisitCompoistElement (this);
 }
public:
 std::list<Element*> childs_;
};

/////////////////////////////////////////////////////////////////////////////
//
// Visitors
//
/////////////////////////////////////////////////////////////////////////////
class VisitorA : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorA::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorA::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorA::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};

class VisitorB : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorB::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorB::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorB::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ElementA         element_a;
 ElementB         element_b;
 CompoisteElement c_element;

 c_element.childs_.push_back (&element_a);
 c_element.childs_.push_back (&element_b);

 VisitorA visitor_a;
 VisitorB visitor_b;

 element_a.Accept (visitor_a);
 element_b.Accept (visitor_a);
 c_element.Accept (visitor_a);

 std::cout << std::endl;

 element_a.Accept (visitor_b);
 element_b.Accept (visitor_b);
 c_element.Accept (visitor_b);

 std::cout << std::endl;
 std::cout << std::endl;
 std::cout << std::endl;


 Element *e;

 std::cout << "by element_a" << std::endl;
 e = &element_a;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by element_b" << std::endl;
 e = &element_b;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by c_element" << std::endl;
 e = &c_element;
 e->Accept (visitor_a);
 e->Accept (visitor_b);

 return 0;
}
-----------------------------------------------------------------------------
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)

VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)


by element_a
VisitorA::VisitElementA (ElementA *)
VisitorB::VisitElementA (ElementA *)

by element_b
VisitorA::VisitElementB (ElementB *)
VisitorB::VisitElementB (ElementB *)

by c_element
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)

Posted by 셈말짓기 :