(C++ : Design-pattern) State Pattern

Posted by : at

Category : Cpp   Design-pattern


#include <iostream>
using namesapce std;

class Character
{
    int gold = 0;
    int item = 0;
public:
    void run() { cout << "run" << endl; }
    void attact() { cout << "attack" << endl; }
};

int main()
{
    Character* p = new Chracter;
    p->run();
    p->attack();
}

item에 따라 run이나 attact함수에 영향을 주고 싶다

// 방법 1
// run, attact에 if문으로 구분을 준다.
void run() { 
    if(item == 1)
        cout << "run : 1" << endl; 
    else if(item == 2)
        cout << "run : 2" << endl;
}

누가 봐도 문제가 있는 방법이군…

문제

  1. 모든 동작에 함수에 조건 분기문이 필요
  2. 새로운 아이템이 추가되면 조건문 속에 조건문이 들어가야한다.
// 방법 2
// 가상함수를 활용하자
class Character
{
    int gold = 0;
    int item = 0;
public:
    void run() { runImp(); }
    void attact() { attackImp(); }

    virtual void runImp() {}
    virtual void attackImp() {}
};

class PowerItemCharater : public Character
{
public:
    virtual void runImp() { cout << "run" << endl;}
}

int main()
{
    Character* p = new Chracter;
    p->run();
    p->attack();

    p = new PowerItemCharatcter;
    p->run();
    p->attack();
}

또 문제는 있다.
위의 방식대로 선언하면 상태(gold정보 등)을 넘길수가 없다.

// 방법 3
struct IState
{
    virtual void run() = 0;
    virtual void attack() = 0;
    virtual ~IState() {}
};

class Character
{
    int gold = 0;
    int item = 0;
    IState* state;
public:
    void changeState(IState* p) { state = p; }

    void run() { state->run(); }
    void attact() { state->attatck(); }
};

class NormalState : public IState
{
    virtual void run() { cout << "run" << endl; }
    virtual void attack() { cout << "power attack" << endl; }
};

int main()
{
    NormalState ns;

    Chracter* p = new Chracter;
    p->changeState(&ns);
    p->run();
}

상태는 변경되지 않고 동작만 변경이 가능하다.


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links