Java/Design Pattern

[헤드퍼스트 디자인 패턴] 12-6. 비지터 패턴

noahkim_ 2024. 12. 19. 00:49

에릭 프리먼 님의 "헤드퍼스트 디자인 패턴" 책을 정리한 포스팅 입니다

 

1. 비지터 패턴

다양한 객체에 새로운 기능을 추가할 경우

 

구성요소

Visitor
  • 새로운 기능을 추가하는 객체
  • 각 객체의 accept 메소드를 호출하여 자신을 전달

 

ConcreteVisitor
  • 각 Element에 대해 수행할 작업 정의

 

Element
  • accept() 메서드를 정의한 객체
  • 자신이 받아들일 수 있는 비지터를 정의

 

장점

  • 객체의 구조를 변경하지 않음
  • 새로운 기능 추가 용이
    • 비지터만 추가하면 됨

 

2. Menu

MenuComponent

// 메뉴 항목을 나타내는 요소 클래스
public abstract class MenuComponent {
    public abstract void accept(MenuVisitor visitor);
}

 

Menu
public class Menu extends MenuComponent {
    private List<MenuComponent> menuComponents = new ArrayList<>();

    public void add(MenuComponent component) { menuComponents.add(component); }

    @Override
    public void accept(MenuVisitor visitor) {
        for (MenuComponent component : menuComponents) component.accept(visitor);
    }
}

 

MenuItem
public class MenuItem extends MenuComponent {
    private String name;
    private double price;

    public MenuItem(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public void accept(MenuVisitor visitor) {
        visitor.visit(this); // 메뉴 아이템에서 방문자를 호출
    }

    public String getName() { return name; }
    public double getPrice() { return price; }
}

 

Ingredient
public class Ingredient extends MenuComponent {
    private String name;

    public Ingredient(String name) {
        this.name = name;
    }

    @Override
    public void accept(MenuVisitor visitor) {
        visitor.visit(this); // 재료에서 방문자를 호출
    }

    public String getName() {
        return name;
    }
}

 

Visitor

public interface MenuVisitor {
    void visit(MenuItem menuItem);
    void visit(Ingredient ingredient);
}
// 비지터 구현: 가격 출력 비지터
public class PricePrinterVisitor implements MenuVisitor {
    @Override
    public void visit(MenuItem menuItem) {
        System.out.println("Menu Item: " + menuItem.getName() + ", Price: $" + menuItem.getPrice());
    }

    @Override
    public void visit(Ingredient ingredient) {
        System.out.println("Ingredient: " + ingredient.getName());
    }
}