비지터 패턴

객체 지향 프로그래밍과 소프트웨어 공학에서 비지터 패턴(visitor pattern; 방문자 패턴)은 알고리즘을 객체 구조에서 분리시키는 디자인 패턴이다. 이렇게 분리를 하면 구조를 수정하지 않고도 실질적으로 새로운 동작을 기존의 객체 구조에 추가할 수 있게 된다. 개방-폐쇄 원칙을 적용하는 방법의 하나이다. #include <iostream> #include <string> using namespace std; // 1. Add an accept(Visitor) method to the "element" hierarchy class Element { public: virtual void accept(class Visitor &v) = 0; }; class This: public Element { public: /*virtual*/void accept(Visitor &v); string this() { return "This"; } }; class That: public Element { public: /*virtual*/void accept(Visitor &v); string that() { return "That"; } }; class TheOther: public Element { public: /*virtual*/void accept(Visitor &v); string theOther() { return "TheOther"; } }; // 2. Create a "visitor" base class w/ a visit() method for every "element" type class Visitor { public: virtual void visit(This *e) = 0; virtual void visit(That *e) = 0; virtual void visit(TheOther *e) = 0; }; /*virtual*/void This::accept(Visitor &v) { v.visit(this); } /*virtual*/void That::accept(Visitor &v) { v.visit(this); } /*virtual*/void TheOther::accept(Visitor &v) { v.visit(this); } // 3. Create a "visitor" derived class for each "operation" to do on "elements" class UpVisitor: public Visitor { /*virtual*/void visit(This *e) { cout << "do Up on " + e->this() << '\n'; } /*virtual*/void visit(That *e) { cout << "do Up on " + e->that() << '\n'; } /*virtual*/void visit(TheOther *e) { cout << "do Up on " + e->theOther() << '\n'; } }; class DownVisitor: public Visitor { /*virtual*/void visit(This *e) { cout << "do Down on " + e->this() << '\n'; } /*virtual*/void visit(That *e) { cout << "do Down on " + e->that() << '\n'; } /*virtual*/void visit(TheOther *e) { cout << "do Down on " + e->theOther() << '\n'; } }; int main() { Element *list[] = { new This(), new That(), new TheOther() }; UpVisitor up; // 4. Client creates DownVisitor down; // "visitor" objects for (int i = 0; i < 3; i++) // and passes each list[i]->accept(up); // to accept() calls for (i = 0; i < 3; i++) list[i]->accept(down); } // OUTPUT // // do Up on This // do Up on That // do Up on TheOther // do Down on This // do Down on That // do Down on TheOther interface CarElementVisitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Body body); void visit(Car car); } interface CarElement { void accept(CarElementVisitor visitor); // CarElements have to provide accept(). } class Wheel implements CarElement { private String name; public Wheel(String name) { this.name = name; } public String getName() { return this.name; } public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Engine implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Body implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Car implements CarElement{ CarElement[] elements; public CarElement[] getElements() { return elements.clone(); // Return a copy of the array of references. } public Car() { this.elements = new CarElement[] { new Wheel("front left"), new Wheel("front right"), new Wheel("back left") , new Wheel("back right"), new Body(), new Engine() }; } public void accept(CarElementVisitor visitor) { for(CarElement element : this.getElements()) { element.accept(visitor); } visitor.visit(this); } } class CarElementPrintVisitor implements CarElementVisitor { public void visit(Wheel wheel) { System.out.println("Visiting "+ wheel.getName() + " wheel"); } public void visit(Engine engine) { System.out.println("Visiting engine"); } public void visit(Body body) { System.out.println("Visiting body"); } public void visit(Car car) { System.out.println("Visiting car"); } } class CarElementDoVisitor implements CarElementVisitor { public void visit(Wheel wheel) { System.out.println("Kicking my "+ wheel.getName() + " wheel"); } public void visit(Engine engine) { System.out.println("Starting my engine"); } public void visit(Body body) { System.out.println("Moving my body"); } public void visit(Car car) { System.out.println("Starting my car"); } } public class VisitorDemo { static public void main(String[] args){ Car car = new Car(); car.accept(new CarElementPrintVisitor()); car.accept(new CarElementDoVisitor()); } } 컴포지트 패턴 “The Visitor design pattern - Structure and Collaboration”. 《w3sDesign.com》. 2017년 8월 12일에 확인함.