Visitor Design [방문자 디자인]
Design Object [디자인목적]
- 보통 OOP설계 시 객체와 처리는 함께 사용
- 방문자 패턴의 경우, 객체에서 처리를 분리하여, 처리가 변경되어도 객체는 변경되지 않도록 한다.
- 컴포짓 패턴과 함께 쓰인다.
Options [대안들]
- 컴포짓 디자인.
Benefit [디자인 장점]
처리[메소드]가 변경되어도, 객체는 변경할 필요가 없다.
객체와 처리가 분리되어 있으므로, 처리부의 추가 및 변경이 용이하다
객체부는 컴포짓 패턴을 이용한다.
Structure & Sample Code [구조와 샘플코드]
객체 처리와 분리
UML
구조
-> Visitable 객체 : 인터페이스
객체 멤버변수[attribute]의 구현
visitor를 받는 accept 메소드 선언
-> Visitor 객체 : 인터페이스
객체의 처리부[method]구현
-> Visitable은 accept(visitor)를 통해 visitor를 받은 뒤, visitor.visit를 통해 데이터 처리
-> Visitor 은 visit(visitable)을 통해 대상 객체에 접근
Source code
Client
import behavioral.visitor.improved.Car;
import behavioral.visitor.improved.Engine;
import behavioral.visitor.improved.Light;
import behavioral.visitor.improved.Wheel;
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.getCarParts().add(new Wheel());
car.getCarParts().add(new Wheel());
car.getCarParts().add(new Wheel());
car.getCarParts().add(new Wheel());
car.getCarParts().add(new Light());
car.getCarParts().add(new Light());
car.getCarParts().add(new Engine());
car.upgrade();
car.print();
car.render();
}
}
- Car
import java.util.ArrayList;
import java.util.List;
public class Car {
// Attribute - car part
List<CarPart> carParts = new ArrayList<CarPart>();
public List<CarPart> getCarParts() {
return carParts;
}
public void setCarParts(List<CarPart> carParts) {
this.carParts = carParts;
}
public void render(){
RenderCarPartVisitor renderer = new RenderCarPartVisitor();
for (CarPart carPart : carParts) {
carPart.acceptCarPartVisitor(renderer);
}
}
public void print(){
PrintCarPartVisitor visitor = new PrintCarPartVisitor();
for (CarPart carPart : carParts) {
carPart.acceptCarPartVisitor(visitor);
}
}
public void upgrade(){
UpgradeCarPartVisitor visitor = new UpgradeCarPartVisitor();
for (CarPart carPart : carParts) {
carPart.acceptCarPartVisitor(visitor);
}
}
}
- CarPart - Visitible <accept>
public abstract class CarPart {
// accpet(visitor)
void acceptCarPartVisitor(CarPartVisitor visitor){
// do visit
visitor.visit(this);
}
}
public class Engine extends CarPart {
}
public class Light extends CarPart {
}
public class Wheel extends CarPart {
}
- CarPartVisitor - Visitor<visit>
public interface CarPartVisitor {
// visit method - implementation specific action
void visit(CarPart carPart);
}
public class PrintCarPartVisitor implements CarPartVisitor{
@Override
public void visit(CarPart carPart) {
System.out.println("Print "+carPart);
}
}
public class RenderCarPartVisitor implements CarPartVisitor{
@Override
public void visit(CarPart carPart) {
System.out.println("Render "+carPart);
}
}
public class UpgradeCarPartVisitor implements CarPartVisitor{
@Override
public void visit(CarPart carPart) {
System.out.println("Upgrade: "+carPart);
}
}