비지터 패턴
소프트웨어 디자인 패턴
(방문자 패턴에서 넘어옴)
객체 지향 프로그래밍과 소프트웨어 공학에서 비지터 패턴(visitor pattern; 방문자 패턴)은 알고리즘을 객체 구조에서 분리시키는 디자인 패턴이다. 이렇게 분리를 하면 구조를 수정하지 않고도 실질적으로 새로운 동작을 기존의 객체 구조에 추가할 수 있게 된다. 개방-폐쇄 원칙을 적용하는 방법의 하나이다.
구조
편집UML 클래스 및 시퀀스 다이어그램
편집클래스 다이어그램
편집예제
편집C++
편집#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일에 확인함.