Post

State Pattern

상태 패턴에 대해 정리합니다.

State Pattern

개요

  • 객체의 상태에 따라 행위를 변경할 수 있게 하는 패턴.

사용하는 경우

  • 객체의 상태에 따라 행위가 달라지는 경우
  • 상태를 클래스로 표현하고, 상태를 변경할 때마다 객체의 행위를 변경하고 싶은 경우

구성요소

  • State: 상태를 나타내는 인터페이스
  • ConcreteState: 상태를 실제로 구현한 클래스
  • Context: 상태를 사용하는 역할

예제

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
#include <iostream>

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

class ConcreteStateA : public State {
public:
    void handle() override {
        std::cout << "ConcreteStateA" << std::endl;
    }
};

class ConcreteStateB : public State {
public:
    void handle() override {
        std::cout << "ConcreteStateB" << std::endl;
    }
};

class Context {
private:
    State* state;

public:
    Context(State* state) : state(state) {}

    void setState(State* state) {
        this->state = state;
    }

    void request() {
        state->handle();
    }
};

int main() {
    State* stateA = new ConcreteStateA();
    State* stateB = new ConcreteStateB();

    Context context(stateA);
    context.request();

    context.setState(stateB);
    context.request();
}

상태 패턴의 장단점

  • 장: 콘텍스트에 영향을 주지 않고 상태를 변경할 수 있다.
  • 단: 상태가 많아질수록 상태 변경 규칙을 파악하기 어려워 진다. 또한, 한 상태 클래스에서 다른 상태 클래서에 대한 의존도가 높아질 수 있다.

vs Strategy Pattern

State PatternStrategy Pattern
객체의 상태에 따라 행위가 달라지는 경우여러 알고리즘이 존재하고, 이 알고리즘을 동적으로 변경해야 하는 경우
상태를 클래스로 표현하고, 상태를 변경할 때마다 객체의 행위를 변경하고 싶은 경우알고리즘을 사용하는 클라이언트와 알고리즘을 구현하는 클래스를 분리하고 싶은 경우
상태를 나타내는 인터페이스(State)와 상태를 사용하는 역할(Context)로 구성전략을 나타내는 인터페이스(Strategy)와 전략을 사용하는 역할(Context)로 구성
상태를 변경할 때마다 객체의 행위를 변경분기문을 사용하여 알고리즘을 선택하는 것이 아닌, 동적으로 알고리즘을 선택하고 싶은 경우
This post is licensed under CC BY 4.0 by the author.