본문 바로가기
💻 programming/design pattern

[c++] Visitor Pattern

by 연구원-A 2020. 12. 16.
반응형

객체 지향 프로그래밍과 소프트웨어 공학에서 비지터 패턴(visitor pattern; 방문자 패턴)은 알고리즘을 객체 구조에서 분리시키는 디자인 패턴입니다. 이렇게 분리를 하면 구조를 수정하지 않고도 실질적으로 새로운 동작을 기존의 객체 구조에 추가할 수 있게 됩니다. 개방-폐쇄 원칙을 적용하는 방법의 하나에 해당합니다.

ko.wikipedia.org/wiki/%EB%B9%84%EC%A7%80%ED%84%B0_%ED%8C%A8%ED%84%B4

 

비지터 패턴 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 둘러보기로 가기 검색하러 가기

ko.wikipedia.org

앞서 말한 것처럼 비지터 패턴은 알고리즘과 객체 구조를 분리시키는 디자인 패턴입니다. 알고리즘을 변경하거나 추가하더라도 기존에 있던 객체 구조를 변경할 필요없이 새로운 동작을 추가할 수 있습니다.

 

Use Case

비지터 패턴은 컴포지트 패턴과 비슷하게 계층적 구조로 형셩되는 데이터를 처리하거나, 구문 트리, 파일시스템 증에 사용하는 것이 일반적입니다. 계층적 구조로 형성되는 데이터를 처리할 때 각각의 노드 클래스에 처리와 관련된 로직을 구현하는 것이 좋기 때문입니다.

 

Class Diagram

  • Visitor: ConcreteElement 들에 대한 처리에 관해 선언합니다. 실제 처리 알고리즘은 포함하지 않습니다.
  • ConcreteVisitor: Visitor의 구현 클래스로, ConcreteElement에 대한 처리 로직을 정의합니다.
  • Element: Visitor를 인자로 받는 Accept 연산을 정의합니다
  • ConcreteElement: Accept를 정의하며 객체의 연산 노드를 담당합니다.

 

Sample Code

www.geeksforgeeks.org/visitor-design-pattern/

 

Visitor design pattern - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

#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

댓글