-
행동(Behavioral) - 방문자(Visitor) 패턴Java/디자인패턴 2024. 11. 18. 09:30반응형
방문자(Visitor) 패턴
방문자(Visitor) 패턴은 행동(Behavioral) 패턴에 속합니다. 이 패턴은 객체 구조와 독립적으로 새로운 동작을 추가하거나 수정할 수 있도록 합니다. 즉, 구조를 변경하지 않고도 기능 확장이 가능하도록 설계됩니다.
방문자 패턴의 특징
- 분리된 동작:
- 객체 구조와 작업(동작)을 분리하여 객체 구조를 변경하지 않고 새로운 동작을 추가할 수 있습니다.
- 기능 확장의 용이성:
- 객체 구조에 다양한 동작을 추가해야 할 때 유용하며, 각 동작이 Visitor 클래스에 별도로 구현됩니다.
- 객체 구조의 안정성:
- 객체 구조(클래스 계층)가 자주 변경되지 않는 경우에 적합합니다.
방문자 패턴의 구성요소
- Visitor (방문자):
- 객체 구조의 각 요소에 대한 동작을 정의합니다.
- 객체 구조의 각 요소를 방문하고, 요소 별 동작을 수행합니다.
- ConcreteVisitor (구체적인 방문자):
- Visitor 인터페이스를 구현하며, 특정 요소에 대한 실제 동작을 정의합니다.
- Element (요소):
- Visitor를 받아들이는 인터페이스를 제공합니다.
- ConcreteElement (구체적인 요소):
- Element를 구현하며 Visitor를 받아들여 해당 동작을 실행합니다.
- ObjectStructure (객체 구조):
- Element들의 집합을 관리하며, 각 Element에 대해 Visitor를 수용하도록 순회합니다.
JAVA 예제
1. Visitor 인터페이스
// Visitor 인터페이스 interface Visitor { void visit(Book book); void visit(Electronics electronics); }
2. ConcreteVisitor 구현
// ConcreteVisitor: 할인 계산기 class DiscountVisitor implements Visitor { @Override public void visit(Book book) { System.out.println("Book: " + book.getTitle() + ", Discounted Price: " + (book.getPrice() * 0.9)); } @Override public void visit(Electronics electronics) { System.out.println("Electronics: " + electronics.getName() + ", Discounted Price: " + (electronics.getPrice() * 0.8)); } }
3. Element 인터페이스
// Element 인터페이스 interface Item { void accept(Visitor visitor); }
4. ConcreteElement 구현
// Book 클래스 class Book implements Item { private String title; private double price; public Book(String title, double price) { this.title = title; this.price = price; } public String getTitle() { return title; } public double getPrice() { return price; } @Override public void accept(Visitor visitor) { visitor.visit(this); } } // Electronics 클래스 class Electronics implements Item { private String name; private double price; public Electronics(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } @Override public void accept(Visitor visitor) { visitor.visit(this); } }
5. ObjectStructure
import java.util.ArrayList; import java.util.List; // 객체 구조 class ShoppingCart { private List<Item> items = new ArrayList<>(); public void addItem(Item item) { items.add(item); } public void applyVisitor(Visitor visitor) { for (Item item : items) { item.accept(visitor); } } }
6. 사용 예시
public class VisitorPatternExample { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); cart.addItem(new Book("Design Patterns", 50.0)); cart.addItem(new Electronics("Headphones", 100.0)); DiscountVisitor discountVisitor = new DiscountVisitor(); System.out.println("Applying discount visitor:"); cart.applyVisitor(discountVisitor); } }
실행 결과
Applying discount visitor: Book: Design Patterns, Discounted Price: 45.0 Electronics: Headphones, Discounted Price: 80.0
장점
- 기능 확장성:
- 객체 구조를 변경하지 않고도 새로운 기능(Visitor)을 쉽게 추가할 수 있습니다.
- 코드의 가독성 증가:
- 각 동작을 Visitor 클래스로 분리해 관리할 수 있습니다.
- 객체 구조의 활용:
- 다양한 타입의 객체에 대해 일관된 방식으로 작업을 수행할 수 있습니다.
단점
- 객체 구조 변경 어려움:
- 객체 구조가 자주 변경되는 경우에는 Visitor 패턴이 적합하지 않을 수 있습니다.
- 유지보수 복잡성:
- 새로운 Element를 추가하려면 기존 Visitor 클래스에도 수정이 필요합니다.
- 복잡도 증가:
- 작은 프로젝트에서는 과도한 설계로 보일 수 있습니다.
이 방문자 패턴은 주로 객체 구조가 안정적이고, 다양한 동작을 추가해야 하는 상황에서 유용합니다. 대표적으로 컴파일러의 구문 트리 처리나 전자 상거래 애플리케이션의 가격 계산 등에 사용됩니다.
반응형'Java > 디자인패턴' 카테고리의 다른 글
구조 패턴(Structural Pattern) - 데코레이터(Decorator) 패턴 (0) 2024.11.20 생성 패턴(Creational Pattern) - 빌더(Builder) 패턴 (0) 2024.11.19 행동(Behavioral) - 중재자(Mediator) 패턴 (0) 2024.11.17 생성(Creational) - 추상 팩토리(Abstract Factory) 패턴 (0) 2024.11.16 구조적(Structural) - 플라이웨이트(Flyweight) 패턴 (1) 2024.11.15 - 분리된 동작: