반응형
객체 지향 프로그래밍과 소프트웨어 공학에서 비지터 패턴(visitor pattern; 방문자 패턴)은 알고리즘을 객체 구조에서 분리시키는 디자인 패턴입니다. 이렇게 분리를 하면 구조를 수정하지 않고도 실질적으로 새로운 동작을 기존의 객체 구조에 추가할 수 있게 됩니다. 개방-폐쇄 원칙을 적용하는 방법의 하나에 해당합니다.
ko.wikipedia.org/wiki/%EB%B9%84%EC%A7%80%ED%84%B0_%ED%8C%A8%ED%84%B4
앞서 말한 것처럼 비지터 패턴은 알고리즘과 객체 구조를 분리시키는 디자인 패턴입니다. 알고리즘을 변경하거나 추가하더라도 기존에 있던 객체 구조를 변경할 필요없이 새로운 동작을 추가할 수 있습니다.
Use Case
비지터 패턴은 컴포지트 패턴과 비슷하게 계층적 구조로 형셩되는 데이터를 처리하거나, 구문 트리, 파일시스템 증에 사용하는 것이 일반적입니다. 계층적 구조로 형성되는 데이터를 처리할 때 각각의 노드 클래스에 처리와 관련된 로직을 구현하는 것이 좋기 때문입니다.
Class Diagram
- Visitor: ConcreteElement 들에 대한 처리에 관해 선언합니다. 실제 처리 알고리즘은 포함하지 않습니다.
- ConcreteVisitor: Visitor의 구현 클래스로, ConcreteElement에 대한 처리 로직을 정의합니다.
- Element: Visitor를 인자로 받는 Accept 연산을 정의합니다
- ConcreteElement: Accept를 정의하며 객체의 연산 노드를 담당합니다.
Sample Code
www.geeksforgeeks.org/visitor-design-pattern/
#include <iostream>
using namespace std;
class Stock
{
public:
virtual void accept(class Visitor *) = 0;
};
class Apple : public Stock
{
public:
/*virtual*/ void accept(Visitor *);
void buy()
{
cout << "Apple::buy\n";
}
void sell()
{
cout << "Apple::sell\n";
}
};
class Google : public Stock
{
public:
/*virtual*/ void accept(Visitor *);
void buy()
{
cout << "Google::buy\n";
}
void sell()
{
cout << "Google::sell\n";
}
};
class Visitor
{
public:
virtual void visit(Apple *) = 0;
virtual void visit(Google *) = 0;
//private:
static int m_num_apple, m_num_google;
void total_stocks()
{
cout << "m_num_apple " << m_num_apple
<< ", m_num_google " << m_num_google << '\n';
}
};
int Visitor::m_num_apple = 0;
int Visitor::m_num_google = 0;
class BuyVisitor : public Visitor
{
public:
BuyVisitor()
{
m_num_apple = m_num_google = 0;
}
/*virtual*/ void visit(Apple *r)
{
++m_num_apple;
r->buy();
cout << "m_num_apple " << m_num_apple << endl;
}
/*virtual*/ void visit(Google *b)
{
++m_num_google;
b->buy();
cout << " m_num_google " << m_num_google << '\n';
}
};
class SellVisitor : public Visitor
{
public:
/*virtual*/ void visit(Apple *a)
{
--m_num_apple;
a->sell();
cout << "m_num_apple " << m_num_apple << endl;
}
/*virtual*/ void visit(Google *g)
{
--m_num_google;
g->sell();
cout << "m_num_google " << m_num_google << endl;
}
};
void Apple::accept(Visitor *v)
{
v->visit(this);
}
void Google::accept(Visitor *v)
{
v->visit(this);
}
int main()
{
Stock *set[] = { new Apple, new Google, new Google,
new Apple, new Apple, 0 };
BuyVisitor buy_operation;
SellVisitor sell_operation;
for (int i = 0; set[i]; i++)
{
set[i]->accept(&buy_operation);
}
buy_operation.total_stocks();
for (int i = 0; set[i]; i++)
{
set[i]->accept(&sell_operation);
}
sell_operation.total_stocks();
}
반응형
'💻 programming > design pattern' 카테고리의 다른 글
[c++] Mediator Pattern (0) | 2020.12.16 |
---|---|
[c++] Observer Pattern (0) | 2020.12.16 |
댓글