-----------------------------------------------------------------------------
[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 *)