-
[Design Pattern] 방문자 패턴 (Visitor Pattern)공부/디자인 패턴 2021. 7. 25. 17:30
방문자 패턴은 방문자와 방문 공간을 분리하여 방문 공간이 방문자를 맞이할 때, 이후에 대한 행동을 방문자에게 위임하는 패턴입니다. 비슷한 객체에서 어떤 동작을 해야할 때 방문자 패턴을 사용하면 수행 로직을 분리할 수 있습니다. 즉, 데이터 구조와 연산을 분리하여 구조를 변경하지 않고 새로운 연산을 추가할 수 있습니다. 새로운 연산을 추가하고 싶으면 새로운 방문자를 추가하면 되는 형식입니다.
클래스 다이어그램
Visitor: Eliment를 방문하고 동작을 구현하기 위한 인터페이스
ConcreteVisitor1, 2: Visitor를 상속받아 실제 동작을 구현한 클래스
Element: visitor가 방문하여 수행해야 하는 대상. 구조를 구성하는 인터페이스
ConcreteElementA, B: Element를 상속받아 실제 동작을 구현한 클래스
ObjectStructure: Element를 갖고 있는 클래스
예시
public interface Element { int accept(Visitor visitor); } public class BagElement implements Element { private final int price; private final String name; public BagElement(int price, String name) { this.name = name; this.price = price; } public int getPrice() { return this.price; } public String getName() { return this.name; } @Override public int accept(Visitor visitor) { return visitor.visit(this); } } public class ShoesElement implements Element { private final int price; private final String name; private final int size; public ShoesElement(int price, String name, int size) { this.price = price; this.name = name; this.size = size; } public int getPrice() { return this.price; } public String getName() { return this.name; } public int getSize() { return this.size; } @Override public int accept(Visitor visitor) { return visitor.visit(this); } } public interface Visitor { int visit(BagElement bagElement); int visit(ShoesElement shoesElement); } public class CartVisitor implements Visitor { @Override public int visit(BagElement bagElement) { System.out.println("가방 이름: "+ bagElement.getName() + "가격: "+ bagElement.getPrice()); return bagElement.getPrice(); } @Override public int visit(ShoesElement shoesElement) { int price = shoesElement.getPrice(); if (shoesElement.getSize() > 270) { price += 2000; } else if (shoesElement.getSize() < 230) { price -= 5000; } System.out.println("신발 이름: "+ shoesElement.getName() + "사이즈: "+ shoesElement.getSize() + "가격: "+ price); return price; } } Element[] elements = new Element[]{ new BagElement(40000, "토트백"), new BagElement(10000, "백팩"), new ShoesElement(50000, "나이키", 210), new ShoesElement(100000, "아디다스", 290), new ShoesElement(156000, "리복", 255) }; Visitor visitor = new CartVisitor(); int totalPrice = 0; for (Element element: elements) { totalPrice += element.accept(visitor); } // 가방 이름: 토트백가격: 40000 // 가방 이름: 백팩가격: 10000 // 신발 이름: 나이키사이즈: 210가격: 45000 // 신발 이름: 아디다스사이즈: 290가격: 102000 // 신발 이름: 리복사이즈: 255가격: 156000 System.out.println("총 금액: "+ totalPrice); // 총 금액: 353000