Programming Languange/디자인 패턴

디자인 패턴 (Design Patterns) - 상태 패턴

타자치는 문돌이

객체의 상태에 따라 다른 행동을 할 때, 상태 패턴(State Pattern)을 활용해 효율적으로 행동을 구현할 수 있다.

컴퓨터 프로그램의 설계에서 자주 쓰이는 개념 중 Finite State Machine(유한 상태 기계)이라는 개념이 있다. Machine은 한 번에 하나의 상태를 가지고, 어떤 이벤트를 통해 다른 상태로 전환될 수 있다.

게임 캐릭터나 몬스터의 상태, 애니메이션에서 이런 설계는 자주 볼 수 있다.

상태에 따라 다른 행동을 하는 객체를 조건문으로 구현할 수도 있으나 이러한 코드는 유지 보수가 매우 어렵다.

 switch (state)
 "draft":
 	state = "moderation"
 	break
 "moderation":
 	if (currentUser.role == "admin")
 		state = "published"
 	break
 "published":
 	// Do nothing.
 	break

구현

상태 패턴은

  • Context
  • State
  • Concrete State
    로 구성된다.

Context는 클라이언트가 객체의 상태 변화를 요청하는 인터페이스를 정의하고 현재 상태를 저장한다.
State는 인터페이스로 Concrete State와 연결한다.
Concrete State는 상태별 메소드를 구현한 클래스이다.

Context

class Context
{
private:
    State* currentState;

public:
    Context()
    {
    	// 초기 상태는 꺼진 상태
    	currentState = new OffState();
    }
    
    void setState(State* state)
    {
    	currentState = state;
    }
    
    void turnOn()
    {
    	currentState->turnOn();
    	setState(new OnState()); // 켤 때 상태를 On으로 변경
    }
    
    void turnOff()
    {
    	currentState->turnOff();
    	setState(new OffState());// 끌 때 상태를 Off로 변경
    }
};

State

class State
{
public:
    virtual void turnOn() = 0;
    virtual void turnOff() = 0;
};

Concrete State

// 켜는 상태를 나타내는 ConcreteState
class OnState : public State
{
public:
    void turnOn() override
    {
    	std::cout << "이미 켜져 있습니다." << std::endl;
    }
    void turnOff() override
    {
    	std::cout << "끄기" << std::endl;
    }
};

// 끄는 상태를 나타내는 ConcreteState
class OffState : public State
{
public:
    void turnOn() override
    {
    	std::cout << "켜기" << std::endl;
    }
    void turnOff() override
    {
    	std::cout << "이미 꺼져 있습니다." << std::endl;
    }
};

예시

int main()
{
    Context bulb; // 전구를 켜고 끄는 행동을 시뮬레이션
    bulb.turnOn();
    bulb.turnOff();
    bulb.turnOn();
    bulb.turnOn();
    bulb.turnOff();

    return 0;
}

장점

  • 단일 책임 원칙을 지킨다.
  • 개방/폐쇄 원칙을 지킨다.

단점

  • 상태가 몇 가지밖에 없다면 상태 패턴을 적용하는 것이 과도할 수도 있다.

 

디자인 패턴 (Design Patterns) - Index