C++/개념정리

상태 패턴

jeongchanhyo 2025. 3. 5. 17:32

상태패턴이란?

객체의 내부 상태가 변경될 때 동작을 전환하도록 하는 디자인 패턴이다.

상태별 동작을 개별 클래스로 분리해 조건문 if-else, switch 복잡도를 제거하는게 핵심 목적이다

왜 if-else를 분리할까?

간단한 조건문은 if-else를 나누면 되지만 조건에 따라 동작하는게 복잡해지고, 또 확작을 계속 하고 싶을 때 유지보수가 힘들어지기 때문이다.

상태패턴 구성 요소

  • Context
    • 상태를 관리하는 주체
  • State Interface
    • 모든 상태의 공통 인터페이스 정의
  • Concrete State
    • 구체적인 상태별 동작 구현
  1. Context가 State 인터페이스에 작업 위임
  2. Concrete State 객체에서 실제 동작 수행
  3. 상태 변경 시 Context의 상태 포인터 갱신

장단점

장점

  • 조건문 감소: 상태 검증 로직 제거 → 코드 가독성 향상
  • 확장성: 새 상태 추가시 기존 코드 수정 불필요(OCP 준수)
  • 책임 분리: 각 상태의 동작이 독립적 클래스에 캡슐화

단점

  • 과도한 클래스 생성: 단순 상태 머신에는 부적합
  • 상호 의존성: Context ↔ State 양방향 참조 시 복잡도 증가

예시

상태 인터페이스

class Lamp;  // 전방 선언

class LampState 
{
public:
    virtual void toggle(Lamp* lamp) = 0;
    virtual ~LampState() = default;
};

구체적인 상태 클래스( Concrete State )

// 켜진 상태
class OnState : public LampState 
{
public:
    void toggle(Lamp* lamp) override;
};

// 꺼진 상태
class OffState : public LampState 
{
public:
    void toggle(Lamp* lamp) override;
};

// 깜빡이는 상태
class BlinkState : public LampState 
{
public:
    void toggle(Lamp* lamp) override;
};

Context클래스

class Lamp 
{
private:
    LampState* currentState;

public:
    Lamp() : currentState(new OffState()) {}

    void setState(LampState* newState) 
    {
        delete currentState;
        currentState = newState;
    }

    void toggle() 
    {
        currentState->toggle(this);
    }

    ~Lamp() 
    {
        delete currentState;
    }
};

// 상태별 동작 구현
void OnState::toggle(Lamp* lamp) 
{
    std::cout << "램프 꺼짐" << std::endl;
    lamp->setState(new OffState());
}

void OffState::toggle(Lamp* lamp) 
{
    std::cout << "램프 켜짐" << std::endl;
    lamp->setState(new OnState());
}

void BlinkState::toggle(Lamp* lamp) 
{
    std::cout << "램프 깜빡임 중지" << std::endl;
    lamp->setState(new OffState());
}

이렇게 펼쳐서 보면 이해가 쉽다. 그래서 전에 배운 전략패턴과 뭐가 다를까?

전략패턴과의 비교

기준 상태 패턴 전략패턴
역할 상태 변화에 따른 동작 변경 알고리즘 교체
변경 주체 상태 객체 자체 외부에서 주입
상호 영향 다른 상태로 전이 가능 전략 독립적 실행

이렇게 된다.

게임에서 사용할 때 

드래곤 퀘스트에서의 공격같은 경우 전략패턴으로 만들면 좋고

이동 애니메이션 등은 상태패턴으로 만들면 좋겠다! 라는 생각이 든다. 행동패턴들은 유사해서 헷갈릴 수 있으니 제대로 기억하도록 하자

'C++ > 개념정리' 카테고리의 다른 글

빌더 패턴  (0) 2025.03.11
템플릿 메서드 패턴  (2) 2025.03.07
전략패턴  (0) 2025.02.26
[디버그 입문]  (1) 2025.02.11
개념정리[연산자(&*)]  (0) 2025.02.07