Programming Languange/디자인 패턴

디자인 패턴 (Design Patterns) - 방문자 패턴

타자치는 문돌이 2024. 4. 15. 17:48

방문자 패턴(Visitor Pattern)은 객체와 기능을 분리할 수 있도록 하는 디자인 패턴이다.

구현

방문자 패턴은

  • Visitor
  • Concrete Visitor
  • Element Interface
  • Element
  • Client
    로 구성된다.
    Visitor 객체는 Element 객체들을 순회하며 각 Element에 필요한 기능을 수행한다.

Visitor

Concrete Visitor의 인터페이스로 각 Concrete Visitor는 매개변수가 다르다.

// Visitor interface
class Visitor {
public:
    virtual void visit(ConcreteElementA* element) = 0;
    virtual void visit(ConcreteElementB* element) = 0;
};

Concrete Visitor

Concrete Element에 맞게 작성된 같은 행동의 여러 버전을 구현한다.

// Concrete visitor
class ConcreteVisitor : public Visitor {
public:
    void visit(ConcreteElementA* element) override {
        std::cout << "Visit ConcreteElementA" << std::endl;
    }

    void visit(ConcreteElementB* element) override {
        std::cout << "Visit ConcreteElementB" << std::endl;
    }
};

Element Interface

Visitor를 수락하는 메소드를 선언한다.

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

Concrete Element

수락 메소드를 구현한다. 메소드가 호출되면 요소에 적당한 Visitor 메소드로 리다이렉트한다.

// Concrete element A
class ConcreteElementA : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visit(this);
    }
};

// Concrete element B
class ConcreteElementB : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visit(this);
    }
};

Client (예시)

visitorelementA, elementB를 (accept를 통해) 방문하고, (visit을 통해) 방문을 처리한다.

int main() {
    ConcreteElementA elementA;
    ConcreteElementB elementB;

    ConcreteVisitor visitor;

    elementA.accept(&visitor);
    elementB.accept(&visitor);

    return 0;
}

장점

  • 개방/폐쇄 원칙을 만족한다. 클래스를 변경하지 않고 클래스의 객체와 작동할 수 있는 새 기능을 추가할 수 있다.
  • 단일 책임 원칙을 만족한다. 같은 행동의 여러 버전을 같은 클래스로 이동할 수 있다.

단점

  • 클래스가 Element에 추가될 때마다 모든 Visitor를 업데이트해야 한다.
  • Visitor가 Element의 Private Field나 메소드에 접근하기 위해 필요한 권한이 부족할 수 있다.

 

디자인 패턴 (Design Patterns) - Index