Visitor_Pattern - 8BitsCoding/RobotMentor GitHub Wiki
๊ฐ์ฒด์ ๊ตฌ์กฐ์ ๊ธฐ๋ฅ์ ๋ถ๋ฆฌ์ํค๋ ํจํด
๊ตฌ์กฐ๋ ๋ณํ์ง ์์ผ๋ฉฐ ๊ธฐ๋ฅ๋ง ๋ฐ๋ก ์ถ๊ฐ๋๊ฑฐ๋ ํ์ฅ๋์ด์ผ ํ ๊ฒฝ์ฐ ์ฌ์ฉ
์ปดํฌ์งํธ ํจํด๊ณผ ์ฐ๋๋์ด ๋ง์ด ์ฌ์ฉ๋๋ค.
ํ๊ณ ์ถ์๊ฒ Car๋ผ๋ ์ค๋ธ์ ํธ์์ Wheel, Engine, Body๋ฅผ ๊ด๋ฆฌํ๊ณ
Visotor๋ฅผ Car๊ฐ acceptํ ์ Visitor์์ ๊ด๋ฆฌํ๋ ์๊ณ ๋ฆฌ์ฆ๋๋ก Car์ ์ค๋ธ์ ํธ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ์ฒ๋ฆฌํ๊ณ ์ถ๋ค.
์๋์ฐจ๋ฅผ ๋ง๋๋ ค๊ณ ํ๋ค.
๊ฐ๊ฐ์ ์๋์ฐจ ํํธ(Wheel, Body, Engine) ์ด ์กด์ฌํ๊ณ ์ปดํฌ์งํธ ํจํด์ ํ์ฉํ Carํด๋์ค๋ฅผ ๊ตฌํ,
Car ํด๋์ค์์๋ ๊ฐ๊ฐ์ ํํธ Element๋ฅผ ์ถ๊ฐํ์ฌ accept ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ visitor ํจํด์ ํธ์ถํ๋ ์์
ํ๊ณ ์ถ์๊ฒ ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ Car์์ Car์ ํจ์(์๊ณ ๋ฆฌ์ฆ) ๊ด๋ฆฌ๋ Visitor์์ ํ๊ณ ์ถ์ ๊ฒ.
int _tmain(int argc, _TCHAR* argv[])
{
// ๋ถํ ์์ฑ
Wheel mWheel[4] = { "front left", "front right", "back left", "back right" };
Engine mEngine;
Body mBody;
Car mCar;
// ํํธ ์ถ๊ฐ
mCar.append(&mWheel[0]);
mCar.append(&mWheel[1]);
mCar.append(&mWheel[2]);
mCar.append(&mWheel[3]);
mCar.append(&mEngine);
mCar.append(&mBody);
// visitor ์์ฑ
CarPrintVisitor mCarPrintVisitor;
CarStartVisitor mCarStartVisitor;
// visitor accept ์ฒ๋ฆฌ
mCar.accept(&mCarPrintVisitor);
mCar.accept(&mCarStartVisitor);
return 0;
}
class Visitor;
class Element
{
public:
virtual void accept(Visitor* v) = 0;
};
class Wheel : public Element
{
public:
Wheel(const TCHAR* name) : mName(name) {}
public:
void accept(Visitor* v) override;
const TCHAR* getName() const { return mName.c_str(); }
private:
tstring mName;
};
class Engine : public Element
{
public:
void accept(Visitor* v) override;
};
class Car : public Element
{
public:
void append(Element* e) { mList.push_back(e); }
void accept(Visitor* v) override;
private:
list<Element*> mList;
};
// Visitor ์ธํฐํ์ด์ค
class Visitor
{
public:
virtual void visit(Wheel* e) = 0;
virtual void visit(Engine* e) = 0;
virtual void visit(Body* e) = 0;
virtual void visit(Car* e) = 0;
};
//------------------------------------------------------------------
// CarPrintVisitor ์์ ํด๋์ค
class CarPrintVisitor : public Visitor
{
public:
void visit(Wheel* e) override { cout << "Visiting " << e->getName() << " Wheel" << endl; }
void visit(Engine* e) override { cout << "Visiting engine" << endl; }
void visit(Body* e) override { cout << "Visiting body" << endl; }
void visit(Car* e) override { cout << "Visiting car" << endl; }
};
//------------------------------------------------------------------
// CarStartVisitor ์์ ํด๋์ค
class CarStartVisitor : public Visitor
{
public:
void visit(Wheel* e) override { cout << "Kicking my " << e->getName() << " Wheel" << endl; }
void visit(Engine* e) override { cout << "Starting my engine" << endl; }
void visit(Body* e) override { cout << "Moving my body" << endl; }
void visit(Car* e) override { cout << "Starting my car" << endl; }
};
// ์ ๋ฐฉ ์ ์ธ์ ๋ฐ๋ฅธ ํ๋จ ๊ตฌํ
void Wheel::accept(Visitor* v) { v->visit(this); }
void Engine::accept(Visitor* v) { v->visit(this); }
void Body::accept(Visitor* v) { v->visit(this); }
// ์ฌ๊ธฐ์ Car์์ accept๋ฅผ ํ ์ Car๊ฐ ๊ด๋ฆฌํ๋ ๋ชจ๋ ์ค๋ธ์ ํธ์ ์ ๊ทผ
void Car::accept(Visitor* v) { for (auto i = mList.begin(); i != mList.end(); ++i) (*i)->accept(v); v->visit(this); }