1. 상태 패턴 (State Pattern)
상태에 따라 다양한 동작을 수행해야할 경우
각 상태 클래스를 만들어 수행할 동작을 위임하는 패턴이다.
2. 상태 패턴의 클래스 구현 방향

각 상태 클래스는 자신의 동작을 캡슐화하고(인터페이스로 구현)
캐릭터(컨텍스트)는 현재 상태 객체에 작업을 위임한다.
3. 상태 패턴 호출 구조

- 캐릭터(컨텍스트)는 현재 상태(StateA)를 설정한다.
- 캐릭터(컨텍스트)는 수행할 행동을 상태 객체에게 위임한다. - Request()
- 상태 객체는 작업을 수행한다.
- 상태 객체는 작업을 수행하고 컨텍스트의 상태 또한 변경할 수 있다. - setState(StateC)
- 캐릭터(컨텍스트)는 수행할 행동을 변경된 상태 객체에게 위임한다. - Request()
- 상태 객체는 작업을 수행한다.
4. 상태 패턴을 언제 적용해야 할까?
- 상태 유형이 많은 경우 (한 번 생각)
- 상태 유형이 많으며 상태별 작업이 크게 달라지는 경우 (고려)
- 상태 유형이 많으며 분기 처리가 많아진 경우
- 상태 유형이 많으며 상태 변경시 중복된 코드가 많아진 경우
5. 상태 패턴 스니펫
1. 상태 인터페이스
class State {
public:
virtual ~State() {}
virtual void Enter(Character* character) = 0;
virtual void Update(Character* character) = 0;
virtual void Exit(Character* character) = 0;
virtual std::string GetName() const = 0;
};
2. 상태 클래스
// Idle 상태
class IdleState : public State {
public:
void Enter(Character* character) override {
std::cout << "Idle: 준비 완료\n";
}
void Update(Character* character) override {
std::cout << "Idle: 대기 중...\n";
}
void Exit(Character* character) override {
std::cout << "Idle: 대기 종료\n";
}
std::string GetName() const override { return "Idle"; }
};
// Running 상태
class RunningState : public State {
public:
void Enter(Character* character) override {
std::cout << "Running: 시작\n";
}
void Update(Character* character) override {
std::cout << "Running: 달리는 중...\n";
}
void Exit(Character* character) override {
std::cout << "Running: 정지\n";
}
std::string GetName() const override { return "Running"; }
};
// Jumping 상태
class JumpingState : public State {
public:
void Enter(Character* character) override {
std::cout << "Jumping: 점프!\n";
}
void Update(Character* character) override {
std::cout << "Jumping: 공중에 있음...\n";
}
void Exit(Character* character) override {
std::cout << "Jumping: 착지 완료\n";
}
std::string GetName() const override { return "Jumping"; }
};
3. 캐릭터 클래스 (컨텍스트)
// Character 클래스
class Character {
private:
std::shared_ptr<State> CurrentState;
public:
void ChangeState(std::shared_ptr<State> newState) {
if (CurrentState) {
std::cout << "Exiting " << CurrentState->GetName() << "\n";
CurrentState->Exit(this);
}
CurrentState = newState;
if (CurrentState) {
std::cout << "Entering " << CurrentState->GetName() << "\n";
CurrentState->Enter(this);
}
}
void Update() {
if (CurrentState) {
CurrentState->Update(this);
}
}
};
4. 상태 패턴 사용
int main() {
Character player;
auto idle = std::make_shared<IdleState>();
auto running = std::make_shared<RunningState>();
auto jumping = std::make_shared<JumpingState>();
player.ChangeState(idle);
player.Update();
player.ChangeState(running);
player.Update();
player.ChangeState(jumping);
player.Update();
return 0;
}
참고
'Design Pattern' 카테고리의 다른 글
| [Design Pattern] 반복자 패턴 (Iterator Pattern) (0) | 2025.04.07 |
|---|---|
| [Design Pattern] 템플릿 메서드 (0) | 2025.04.04 |
| [Design Pattern] 전략 패턴 (0) | 2025.04.02 |
| [Design Pattern] 디자인 패턴 (0) | 2025.04.01 |
| [DesignPattern] 모던 객체지향 설계 - 활용 예시 (0) | 2025.04.01 |