목차
1. Visitor Pattern 이란?
2. Visitor Pattern 클래스 다이어그램 예시
3. 코드 예시
4. 실행 결과
Visitor Pattern 이란?
데이터 구조와 데이터 처리를 분리해주는 패턴 입니다.
데이터 처리 방식을 기존의 소스 코드 변경 없이 새로운 클래스 추가만으로 확장할 수 있으므로
개방-폐쇠 원칙을 준수할 수 있습니다.
데이터 구조는 Composite Pattern 을 사용해 표현을 사용합니다.
Visitor Pattern 클래스 다이어그램 예시
이름 | 내용 |
Unit | 데이터 구조를 나타내는 클래스 |
Item | 단일 데이터 하나의정수 값을 가진 클래스 |
ItemList | Unit 타입의 객체를 여러개 가질수 있도록 하여 단일데이터나집합데이터를 포함할 수 있도록 하는 클래스 |
Visitor | 데이터 처리를 담당하는 클래스 |
SumVisitor | 데이터가 가지고 있는 정수 값을 합하는 기능을 가진 클래스 |
AvgVisitor | 데이터가 가지고 있는 정수 값을 평균내는 기능을 가진 클래스 |
Unit 에서 accept 메서드로 Visitor 객체의 방문을 허락해 줍니다.
Visitor 에서는 visit 메서드로 허락된 데이터를 처리합니다.
코드 예시
Unit 인터페이스
Visitor 의 방문을 허락해줄 accept 메서드를 정의합니다.
public interface Unit {
void accept(Visitor visitor);
}
Item 클래스
Unit 을 구현합니다.
accept 메서드를 통해 visitor 의 방문(visit)을 허락해 줍니다.
public class Item implements Unit {
private int value;
public Item(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
ItemList 클래스
accept 메서드를 구현합니다.
배열에 담긴 Unit 들의 방문(visit)을 허용(accept)해줍니다.
public class ItemList implements Unit {
private ArrayList<Unit> list = new ArrayList<>();
public void add(Unit unit) {
list.add(unit);
}
@Override
public void accept(Visitor visitor) {
Iterator<Unit> iter = list.iterator();
while(iter.hasNext()) {
Unit unit = iter.next();
visitor.visit(unit);
}
}
}
Visitory 인터페이스
Unit 을 방문할 visit 메서드를 정의합니다.
public interface Visitor {
void visit(Unit unit);
}
SumVisitor 클래스
visit 메서드를 구현합니다.
Item 클래스일 경우 값을 가져와서 더해주고, 아닐 경우 accept 를 하여 visit 를 허용합니다.
public class SumVisitor implements Visitor {
private int sum = 0;
public int getValue() {
return sum;
}
@Override
public void visit(Unit unit) {
if(unit instanceof Item) {
sum += ((Item)unit).getValue();
} else {
unit.accept(this);
}
}
}
AvgVisitor 클래스
마찬가지로 visit 메서드를 구현합니다.
public class AvgVisitor implements Visitor {
private int sum = 0;
private int count = 0;
public double getValue() {
return sum / count;
}
@Override
public void visit(Unit unit) {
if(unit instanceof Item) {
sum += ((Item)unit).getValue();
count++;
} else {
unit.accept(this);
}
}
}
실행 결과
Main 클래스
ItemList1, ItemList2, ItemList3 을 만들어 각각 원하는 만큼 정수값을 가진 Item 을 담습니다.
이후 가장 상위 배열인 ItemList1 을 accept 해주어 Visitor의 방문을 허락해 줍니다.
이때 SumVisitor 나 AvgVisitor 를 전달하여 어떤 방식으로 동작할지 선택합니다.
SumVIsitor 를 전달해 주었다면 모든 데이터가 합으로 나올 것이고,
AvgVisitor 를 전달해 주었다면 평균으로 나올것입니다.
public class Main {
public static void main(String[] args) {
ItemList list1 = new ItemList();
list1.add(new Item(10));
list1.add(new Item(15));
list1.add(new Item(20));
ItemList list2 = new ItemList();
list2.add(new Item(25));
list2.add(new Item(30));
list1.add(list2);
ItemList list3 = new ItemList();
list3.add(new Item(35));
list2.add(list3);
SumVisitor sum = new SumVisitor();
list1.accept(sum);
System.out.println("합계: " + sum.getValue());
AvgVisitor avg = new AvgVisitor();
list1.accept(avg);
System.out.println("평균: " + avg.getValue());
}
}
실행 결과
합계: 135
평균: 22.0
참조
https://www.youtube.com/watch?v=QC8Q5MWB-mQ
'Design Pattern > 구조(Structural) 패턴' 카테고리의 다른 글
10. 데코레이터 패턴 / Decorator Pattern (0) | 2023.11.08 |
---|---|
8. 프록시 패턴 / Proxy Pattern (1) | 2023.11.03 |
6. 브리지 패턴 (Bridge Pattern) (2) | 2023.11.01 |
4. 컴포지트 패턴 (Composite Pattern) (0) | 2023.10.30 |
3. 어댑터 패턴 (Adapter Pattern) (0) | 2023.10.29 |