반응형
1. 비지터 패턴이란?
비지터(Visitor) 패턴은 객체의 구조와 동작을 분리하는 디자인 패턴입니다. 객체 구조는 변하지 않지만, 구조 내에 포함된 요소들에 대해 수행하는 동작(알고리즘)이 자주 변경될 때 유용하게 사용됩니다.
즉, 객체 구조는 그대로 두고 방문자(Visitor) 객체를 통해 새로운 기능을 추가하는 방식입니다.
비지터 패턴은 행동(Behavioral) 패턴 중 하나로, 각 요소의 구체적인 동작을 Visitor 클래스에서 처리합니다.
2. 비지터 패턴의 특징
- 객체 구조와 연산의 분리: 객체 구조는 고정되지만, 새로운 동작(알고리즘)을 Visitor를 통해 추가할 수 있습니다.
- 유연한 동작 추가: 기존 클래스의 변경 없이 새로운 기능을 추가할 수 있습니다.
- 더블 디스패치(Double Dispatch): 두 개의 객체가 서로 상호작용하는 패턴으로, 실행될 메서드를 동적으로 결정합니다.
3. 비지터 패턴의 장점과 단점
장점
- 기능 확장성: 기존 클래스의 변경 없이 새로운 동작을 추가할 수 있습니다.
- 개방-폐쇄 원칙(OCP) 준수: 객체 구조를 수정하지 않고 확장할 수 있습니다.
- 유지보수 용이: 동작(알고리즘)을 Visitor 클래스에 모아 관리할 수 있습니다.
단점
- 객체 구조에 종속적: 객체 구조에 변화가 생기면 Visitor 인터페이스와 구현 클래스도 모두 수정해야 합니다.
- 복잡한 구조: 요소가 많아질수록 비지터 클래스와 메서드가 복잡해질 수 있습니다.
- 더블 디스패치로 인한 번거로움: 두 객체의 상호작용을 처리하기 위해 코드가 번거로울 수 있습니다.
4. 비지터 패턴 클래스 다이어그램
+------------------+ +-------------------+
| Element |<------------| Visitor |
+------------------+ +-------------------+
| + accept() | | + visitA(ElementA)|
+------------------+ | + visitB(ElementB)|
^ +-------------------+
|
+------------------+
| ConcreteElementA|
+------------------+
| + accept() |
+------------------+
+------------------+
| ConcreteElementB|
+------------------+
| + accept() |
+------------------+
+-------------------+
| ConcreteVisitor |
+-------------------+
| + visitA() |
| + visitB() |
+-------------------+
5. 예제 코드
비지터 패턴 구현 (Java)
// Visitor 인터페이스
interface Visitor {
void visit(ElementA element);
void visit(ElementB element);
}
// Element 인터페이스
interface Element {
void accept(Visitor visitor);
}
// Concrete Element A
class ElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA() {
System.out.println("ElementA의 동작 수행");
}
}
// Concrete Element B
class ElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB() {
System.out.println("ElementB의 동작 수행");
}
}
// Concrete Visitor
class ConcreteVisitor implements Visitor {
@Override
public void visit(ElementA element) {
System.out.println("ConcreteVisitor가 ElementA 방문");
element.operationA();
}
@Override
public void visit(ElementB element) {
System.out.println("ConcreteVisitor가 ElementB 방문");
element.operationB();
}
}
// 클라이언트 코드
public class VisitorPatternExample {
public static void main(String[] args) {
Element[] elements = {new ElementA(), new ElementB()};
Visitor visitor = new ConcreteVisitor();
for (Element element : elements) {
element.accept(visitor);
}
}
}
실행 결과
ConcreteVisitor가 ElementA 방문
ElementA의 동작 수행
ConcreteVisitor가 ElementB 방문
ElementB의 동작 수행
6. 마무리
비지터 패턴은 객체 구조와 동작을 분리하여 새로운 기능을 추가할 때 유용합니다. 특히 구조는 고정되어 있지만 동작이 자주 바뀌는 경우에 적용하기 좋습니다.
하지만 구조에 변경이 생기면 비지터 패턴의 유연성이 떨어질 수 있으므로, 상황에 맞게 선택하는 것이 중요합니다.
반응형
'JAVA > JAVA Design Pattern' 카테고리의 다른 글
프로젝트에서의 디자인 패턴 적용 사례 및 주의점 (0) | 2025.01.07 |
---|---|
JAVA 이터레이터(Iterator) 패턴 (0) | 2025.01.06 |
JAVA 상태(State) 패턴 (0) | 2025.01.04 |
JAVA 템플릿 메서드 (Template Method) 패턴 (0) | 2025.01.03 |
JAVA 커맨드 패턴(Command Pattern) (0) | 2025.01.02 |