Thinking Different







State Pattern - 상태 패턴

  • 객체의 상태에 따라 각각의 행위를 변경할 수 있게 캡슐화한다
  • 동적으로 행동을 교체할 수 있다
  • Strategy Pattern (전략 패턴) 과 구조는 거의 동일하나 쓰임의 용도가 다르다



샘플 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//------------------------------------------------------------------
// State 인터페이스 클래스
class State
{
public:
    virtual void handle() = 0;
};
 
//------------------------------------------------------------------
// ConcreteState1 클래스
class ConcreteState1 : public State
{
public:
    void handle() override { cout << "ConcreteState1" << endl; }
};
 
//------------------------------------------------------------------
// ConcreteState2 클래스
class ConcreteState2 : public State
{
public:
    void handle() override { cout << "ConcreteState2" << endl; }
};
 
//------------------------------------------------------------------
// Context 클래스
class Context
{
public:
    Context(State* state) : pState(state) {}
    ~Context() { if (pState) delete pState; }
 
public:
    void SetState(State* state) { if (pState) delete pState; pState = state; }
    void request() { pState->handle(); }
 
private:
    State* pState;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Context* pContext = new Context(new ConcreteState1());
    pContext->request();
 
    pContext->SetState(new ConcreteState2());
    pContext->request();
 
    delete pContext;
    return 0;
}



예제를 통한 상태 패턴(State Pattern) 알아보기



예제) 몬스터 AI 처리




하나의 몬스터가 있으며, 그 몬스터는 3가지(이동, 공격, 아이템줍기) 상태를 가진다.  몬스터 AI를 상태패턴을 이용하여 간단히 구현한 예제이다.



예제 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//------------------------------------------------------------------
// 상태 인터페이스 클래스
class 상태_인터페이스
{
public:
    virtual void 처리() = 0;
};
 
//------------------------------------------------------------------
// 이동 클래스
class 이동 : public 상태_인터페이스
{
public:
    void 처리() override { cout << "이동" << endl; }
};
 
//------------------------------------------------------------------
// 공격 클래스
class 공격 : public 상태_인터페이스
{
public:
    void 처리() override { cout << "공격" << endl; }
};
 
//------------------------------------------------------------------
// 아이템 줍기 클래스
class 아이템줍기 : public 상태_인터페이스
{
public:
    void 처리() override { cout << "아이템줍기" << endl; }
};
 
//------------------------------------------------------------------
// 몬스터(Context) 클래스
class 몬스터
{
public:
    몬스터(상태_인터페이스* state) : pState(state) {}
    ~몬스터() { if (pState) delete pState; }
 
public:
    void 상태변경(상태_인터페이스* state) { if (pState) delete pState; pState = state; }
    void 처리() { pState->처리(); }
 
private:
    상태_인터페이스* pState;
};
 
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    몬스터* pMonster = new 몬스터(new 이동());
    pMonster->처리();
 
    pMonster->상태변경(new 공격());
    pMonster->처리();
 
    pMonster->상태변경(new 아이템줍기());
    pMonster->처리();
 
    delete pMonster;
    return 0;
}


예제 결과)