ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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

    댓글