1) 개요
방문자 패턴은 로직을 객체 구조에서 분리 시키는 디자인 패턴입니다.
비슷한 종류의 객체들을 가진 그룹에서 작업을 수행해야 할 때 주로 사용되는 패턴입니다.
- 장점
1. 로직이 추가/변경되면 그 로직이 포함된 클래스를 찾아가며 변경하지 않고 방문자 객체만 변경하면 됩니다.
- 단점
1. 방문자 인터펭스에 구현해야할 로직이 많으면 유지보수에 어려움이 있습니다.
2. visit 메소드의 return 타입을 각각 파악하고 있어야 합니다.
2) UML
- Client : 명령을 보냅니다.
- Visitor : 명령을 수행하기 위해 필요한 메소드를 정의하는 인터페이스입니다.
- ConcreteVisitor : 명령을 수행하는 메소드를 구현합니다.
- Element : Visit를 사용할 수 있는지 확인하는 accept 메소드를 정의하는 인터페이스입니다.
- ConcreteElement : Visitable에서 정의된 accept 메소드를 구현하며 Visitor객체는 이 객체를 통하여 명령이 전달됩니다.
3) 예제
1 2 3 4 | public interface ItemElement { public int accept(ShoppingCartVisitor visitor); } | cs |
1 2 3 4 5 | public interface ShoppingCartVisitor { int visit(Book book); int visit(Fruit fruit); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class Book implements ItemElement{ private int price; private String isbnNumber; public Book(int cost, String isbn) { this.price = cost; this.isbnNumber = isbn; } public int getPrice() { return price; } public String getIsbnNumber() { return isbnNumber; } @Override public int accept(ShoppingCartVisitor visitor) { return visitor.visit(this); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class Fruit implements ItemElement{ private int pricePerKg; private int weight; private String name; public Fruit(int priceKg, int weight, String name) { this.pricePerKg = priceKg; this.weight = weight; this.name = name; } public String getName() { return name; } public int getPricePerKg() { return pricePerKg; } public int getWeight() { return weight; } @Override public int accept(ShoppingCartVisitor visitor) { return visitor.visit(this); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class ShoppingCartVisitorImpl implements ShoppingCartVisitor{ @Override public int visit(Book book) { int cost = 0; if(book.getPrice() > 50) cost = book.getPrice()-5; else cost = book.getPrice(); System.out.println("Book ISBN : " + book.getIsbnNumber() + " cost = " + cost); return cost; } @Override public int visit(Fruit fruit) { int cost = fruit.getPricePerKg() * fruit.getWeight(); System.out.println(fruit.getName() + " cost = " + cost); return cost; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class ShoppingCartClient { public static void main(String[] args) { ItemElement[] items = new ItemElement[] {new Book(20, "What is Justice?"), new Book(100, "DesignPattern"), new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")}; int total = calculatePrice(items); System.out.println("Total Cost = " + total); } private static int calculatePrice(ItemElement[] items) { ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl(); int sum = 0; for (ItemElement item : items) { sum = sum + item.accept(visitor); } return sum; } } | cs |
'IT > 디자인 패턴(Design Pattern)' 카테고리의 다른 글
[디자인 패턴] 상태 패턴(State Pattern) (0) | 2019.02.15 |
---|---|
[디자인 패턴] 템플릿메소드 패턴(TemplateMethod Pattern) (0) | 2019.02.14 |
[디자인 패턴] 메멘토 패턴(Memento Pattern) (0) | 2019.02.13 |
[디자인 패턴] 중재자 패턴(Mediator Pattern) (0) | 2019.02.12 |
[디자인 패턴] 이터레이터 패턴(Iterator Pattern) (0) | 2019.02.11 |