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