비지터 패턴은 객체 구조(Object Structure)와 그 구조를 구성하는 요소(Element) 위에 정의된 연산을 분리하여, 새로운 연산을 기존 요소 클래스를 수정하지 않고도 추가할 수 있도록 설계된 클래스 디자인 패턴이다. 객체지향 프로그래밍에서 행위(behavior)를 객체 구조와 분리함으로써 다형성(Polymorphism)을 활용하고, 개방-폐쇄 원칙(Open/Closed Principle)을 지원한다.
기본 구조
- Visitor – 연산을 선언하는 인터페이스 혹은 추상 클래스. 각 구체적 연산은
visit(Element e)형태의 메서드로 정의한다. - ConcreteVisitor – Visitor 인터페이스를 구현하며, 요소 타입별로 구체적인 연산 로직을 제공한다.
- Element –
accept(Visitor v)메서드를 선언한다. 구현 클래스는v.visit(this)를 호출하여 방문자를 전달한다. - ConcreteElement – Element를 구현한 클래스들. 각각의
accept구현을 통해 자신을 Visitor에게 전달한다. - ObjectStructure – Element 객체들을 관리하고, 필요 시 모든 요소에 Visitor를 적용한다(예:
forEach(e -> e.accept(visitor))).
적용 사례
- 컴파일러: 추상 구문 트리(AST)의 각 노드에 대해 타입 검사, 코드 생성, 최적화 등 다양한 작업을 Visitor로 구현한다.
- 그래프·트리 순회: 노드에 추가적인 연산(예: 통계 수집, 시각화)을 실행할 때 구조를 변경하지 않고 Visitor를 이용한다.
- UI 프레임워크: 컴포넌트 트리에 대해 렌더링, 레이아웃 계산, 이벤트 전달 등을 Visitor 형태로 분리한다.
장점
- 알고리즘을 객체 구조에서 독립시켜 새로운 연산을 쉽게 추가 가능.
- 요소 클래스가 변하지 않으므로 클래스 캡슐화를 유지.
- 다양한 요소 타입에 대해 공통 인터페이스를 통해 일관된 연산을 제공.
단점
- 요소 클래스가 Visitor에 의존하게 되며, 요소가 추가될 경우 모든 Visitor를 수정해야 한다.
- 복잡한 객체 구조에서는 Visitor와 요소 간의 이중 디스패치(double dispatch) 구현이 난해할 수 있다.
어원 및 역사
비지터 패턴은 1994년 《Design Patterns: Elements of Reusable Object‑Oriented Software》(Gang of Four, GoF)에서 제시된 23가지 디자인 패턴 중 하나이다. 원어 ‘Visitor’는 ‘방문자’를 의미하며, 방문자가 객체 구조를 “방문”하면서 연산을 수행한다는 메타포를 반영한다. 한국어로는 ‘비지터 패턴’ 혹은 ‘Visitor 패턴’이라고 표기한다.