
C++로 작성된 상태
상태는 객체의 내부 상태가 변경될 때 해당 객체가 행동을 변경할 수 있도록 하는 행동 디자인 패턴입니다.
패턴은 상태 관련 행동들을 별도의 상태 클래스들로 추출하며 또 원래 객체가 자체적으로 작동하는 대신 위에 언급된 클래스들에 작업을 위임하도록 강제합니다.
복잡도:
인기도:
사용 사례들: 상태 패턴은 일반적으로 C++에서 대규모 switch
기반 상태 머신들을 객체들로 변환하는 데 사용됩니다.
식별: 객체들의 상태에 따라 행동을 변경하는 메서드들이 있으면 패턴은 상태 패턴으로 초기 식별될 수 있으며 이 상태가 상태 객체들 자체를 포함하여 다른 객체들에 의해 제어되거나 대체될 수 있으면 해당 패턴은 상태 패턴입니다.
개념적인 예시
이 예시는 상태 디자인 패턴의 구조를 보여주고 다음 질문에 중점을 둡니다:
- 패턴은 어떤 클래스들로 구성되어 있나요?
- 이 클래스들은 어떤 역할을 하나요?
- 패턴의 요소들은 어떻게 서로 연관되어 있나요?
main.cc: 개념적인 예시
#include <iostream> #include <typeinfo> /** * The base State class declares methods that all Concrete State should * implement and also provides a backreference to the Context object, associated * with the State. This backreference can be used by States to transition the * Context to another State. */ class Context; class State { /** * @var Context */ protected: Context *context_; public: virtual ~State() { } void set_context(Context *context) { this->context_ = context; } virtual void Handle1() = 0; virtual void Handle2() = 0; }; /** * The Context defines the interface of interest to clients. It also maintains a * reference to an instance of a State subclass, which represents the current * state of the Context. */ class Context { /** * @var State A reference to the current state of the Context. */ private: State *state_; public: Context(State *state) : state_(nullptr) { this->TransitionTo(state); } ~Context() { delete state_; } /** * The Context allows changing the State object at runtime. */ void TransitionTo(State *state) { std::cout << "Context: Transition to " << typeid(*state).name() << ".\n"; if (this->state_ != nullptr) delete this->state_; this->state_ = state; this->state_->set_context(this); } /** * The Context delegates part of its behavior to the current State object. */ void Request1() { this->state_->Handle1(); } void Request2() { this->state_->Handle2(); } }; /** * Concrete States implement various behaviors, associated with a state of the * Context. */ class ConcreteStateA : public State { public: void Handle1() override; void Handle2() override { std::cout << "ConcreteStateA handles request2.\n"; } }; class ConcreteStateB : public State { public: void Handle1() override { std::cout << "ConcreteStateB handles request1.\n"; } void Handle2() override { std::cout << "ConcreteStateB handles request2.\n"; std::cout << "ConcreteStateB wants to change the state of the context.\n"; this->context_->TransitionTo(new ConcreteStateA); } }; void ConcreteStateA::Handle1() { { std::cout << "ConcreteStateA handles request1.\n"; std::cout << "ConcreteStateA wants to change the state of the context.\n"; this->context_->TransitionTo(new ConcreteStateB); } } /** * The client code. */ void ClientCode() { Context *context = new Context(new ConcreteStateA); context->Request1(); context->Request2(); delete context; } int main() { ClientCode(); return 0; }
Output.txt: 실행 결과
Context: Transition to 14ConcreteStateA. ConcreteStateA handles request1. ConcreteStateA wants to change the state of the context. Context: Transition to 14ConcreteStateB. ConcreteStateB handles request2. ConcreteStateB wants to change the state of the context. Context: Transition to 14ConcreteStateA.