상태(State) 패턴

2023. 3. 19. 18:04·C++/디자인 패턴

디자인 패턴 중 행위 패턴인 상태 패턴은 객체 상태를 캡슐화함으로써 참조하게 하는 방식으로 상태에 따라 다르게 처리할 수 있도록 내용을 변경하여, 변경 시 원시 코드의 수정을 최소화할 수 있고, 유지보수의 편의성도 갖는 디자인 패턴이다.

즉, 객체 상태에 따라 동작이 달라지는 경우 사용되는 디자인 패턴으로 객체를 상태(state)와 상태에 따른 동작(action)으로 분리하여 구현하고, 객체의 상태가 변할 때마다 적절한 상태에 맞는 동작을 수행하도록 한다.

 

자기 스스로 상태를 판단해 행동하도록 하는 것인데, 이는 유한 상태 기계(FSM)와 밀접한 관련이 있음

* 유한 상태 기계(FSM): 상태(State)와 상태 전환(Transition)으로 이루어진 모델로, 각 상태에서는 특정 동작을 수행하며 입력이 발생하면 다음 상태로 전환됨

 

FSM은 상태 변화에 따라 시스템의 동작을 제어하는 것이 목적

상태와 전환을 그래프로 나타낼 수 있으며, 이를 상태 전이도(State Transition Diagram)이라고 함

Unreal Engine의 애님그래프

 

쉽게 예를 들어, 자판기를 구현한다고 가정한다.

자판기의 상태는 "돈 투입 대기 상태", "음료 선택 대기 상태", "음료 추출 상태" 등 여러 상태를 가질 수 있는데,

각 상태에 따라 사용자의 동작이 달라지며 자판기의 동작도 달라져야 함

 

이러한 경우 상태 패턴을 사용해 구현할 수 있다. 상태 패턴에서는 자판기를 하나의 객체로 구현하는 대신, 각 상태를 객체로 분리해 구현한다.

그러면 각 상태에 맞는 동작을 쉽게 구현할 수 있으며, 상태 전환에 따른 동작 변경도 쉽게 할 수 있다.

 

간단한 예시

#include <iostream>

using namespace std;

class LightState {
public:
    virtual void switchOn() = 0;
    virtual void switchOff() = 0;
};

class OnState : public LightState {
public:
    void switchOn() {
        cout << "이미 켜져 있습니다." << endl;
    }
    void switchOff() {
        cout << "불을 끕니다." << endl;
    }
};

class OffState : public LightState {
public:
    void switchOn() {
        cout << "불을 켭니다." << endl;
    }
    void switchOff() {
        cout << "이미 꺼져 있습니다." << endl;
    }
};

class Light {
private:
    LightState* state;
public:
    Light() {
        state = new OffState();
    }
    void setState(LightState* state) {
        this->state = state;
    }
    void switchOn() {
        state->switchOn();
    }
    void switchOff() {
        state->switchOff();
    }
};

int main() {
    Light light;

    light.switchOn();  // "불을 켭니다."
    light.switchOff(); // "불을 끕니다."

    light.setState(new OnState());
    light.switchOn();  // "이미 켜져 있습니다."
    light.switchOff(); // "불을 끕니다."

    return 0;
}

 

 

FSM 요점

  • 가질 수 있는 상태가 한정되어 있음(유한한 한정)
  • 한 번에 한 가지의 상태만 될 수 있음
  • 입력이나 이벤트에 따라 상태 전이가 일어나고 이를 반복하며 최종 상태에 도달함
  • 상태와 전이로 구성되므로 적절히 정의해 시스템의 동작을 모델링 할 수 있음 (Enum과 switch~case문으로 구현할 수 있음) 따라서, 간단하고 직관적인 모델링을 가능하게 함

 

FSM을 사용하면 좋을 때

  • 내부 상태에 따라 객체 동작이 바뀔 때
  • 상태 선택지가 많지 않을 때
  • 객체 입력이나 이벤트에 따라 반응할 때

 

문제점

  • 상태 조합이 안 된다. 예를 들어, 점프 중에 공격하기...
  • 상태가 많아지면 매우 복잡해짐(거미줄처럼 여기저기 얽혀 있는 상태들)

유니티 State Machine

  • 입력에 따라 시스템의 상태가 변경되므로 시스템의 복잡도가 증가할수록 입력에 대한 처리가 어려워짐

 

상태 패턴의 요점

  • 상태 패턴은 상태와 상태 전이로 구성된 유한 상태 기계 모델을 사용함
  • 객체의 동작을 변경하는 것이 목적이며, 객체는 내부적으로 상태를 가지고 있음
  • 상태에 따라 객체가 다른 동작을 수행하며, 이를 구현하는 방식으로 상태 클래스를 정의하고 이를 객체에 적용함

 

장점

  1. 코드의 유지 보수성이 향상됨. 새로운 상태가 추가되거나 상태의 동작이 변경되어도 상태 클래스만 수정하면 됨
  2. 객체의 동작이 상태에 따라 변경되므로 코드가 간단하고 가독성이 좋아짐
  3. 코드의 중복을 제거할 수 있음

 

단점

  1. 객체가 다양한 상태를 가지고 있을 때 상태 클래스가 매우 많아질 수 있음
  2. 상태 패턴을 적용하면 클래스의 수가 많아지므로 코드의 복잡도가 증가할 수 있음 → 따라서, 상태의 수와 전이 수를 적절하게 관리하고, 객체 간의 결합도를 줄이기 위해 인터페이스와 추상 클래스를 적극 활용하는 것이 좋음

 

 

'C++ > 디자인 패턴' 카테고리의 다른 글

관찰자(Observer) 패턴  (0) 2023.03.14
싱글턴(Singleton) 패턴  (1) 2023.03.12
경량(Flyweight) 패턴  (3) 2023.03.11
디자인 패턴  (2) 2023.03.11
명령(Command) 패턴  (2) 2023.03.11
'C++/디자인 패턴' 카테고리의 다른 글
  • 관찰자(Observer) 패턴
  • 싱글턴(Singleton) 패턴
  • 경량(Flyweight) 패턴
  • 디자인 패턴
KimMK
KimMK
  • KimMK
    KimMK
    KimMK
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Unreal
      • Git
      • C++
        • 디자인 패턴
        • STL
      • 자료구조 & 알고리즘
      • Portfolio
        • Unreal C
        • Unreal BP
      • Baekjoon
        • 분할정복
        • BFS(너비우선탐색)
        • DFS(깊이우선탐색)
        • 탐욕(Greedy)
        • 동적계획법(DP)
        • 기하학
        • 백트래킹
        • 트리
        • 구현
      • Portfolio 개발 진행중
        • 개발 진행 중
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    경량 패턴
    트리순회
    유니온-파인드
    Factory method pattern
    Unreal Collision
    C++ STL 정리
    명령패턴
    리플렉션
    분포 기반 정렬 알고리즘
    Union-Find
    트리
    두 직선사이 교점
    Set
    깊이 우선 탐색
    command pattern
    생성패턴
    비교 기반 정렬 알고리즘
    object channel
    언리얼 프로퍼티 시스템
    동적 계획법
    스택
    BFS
    자료구조
    디자인패턴
    flyweight pattern
    Abstract Factory pattern
    Trie
    관찰자(Observer) 패턴
    unreal insight
    Queue
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
KimMK
상태(State) 패턴
상단으로

티스토리툴바