Visitor_Pattern - 8BitsCoding/RobotMentor GitHub Wiki

์ •์˜

๊ฐ์ฒด์˜ ๊ตฌ์กฐ์™€ ๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌ์‹œํ‚ค๋Š” ํŒจํ„ด

๊ตฌ์กฐ๋Š” ๋ณ€ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ธฐ๋Šฅ๋งŒ ๋”ฐ๋กœ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ํ™•์žฅ๋˜์–ด์•ผ ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ

์ปดํฌ์ง€ํŠธ ํŒจํ„ด๊ณผ ์—ฐ๋™๋˜์–ด ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.


๋‹ค์ด์–ด๊ทธ๋žจ

image

ํ•˜๊ณ ์‹ถ์€๊ฒŒ 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); }

์ฐธ๊ณ ์‚ฌ์ดํŠธ

โš ๏ธ **GitHub.com Fallback** โš ๏ธ