설명
객체의 행동이 상태에 따라 바뀐다면 바뀌는 행동과 상태를 하나의 클래스로 만듬.
조건분기를 클래스의 다형성으로 해결하므로 Context 의 유지보수가 쉬워짐.
자신의 상태를 바꾸는 것은 State 의 메소드에서 해결하는 것이 하나의 테크닉.
State 는 Flyweight 나 Singleton 으로 구현하는게 보통임.
예제 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class TCPConnection { public: TCPConnection(); void Close(); private: friend class TCPState; void ChangeState(TCPState* s) { _state = s; } private: TCPState* _state; }; | cs |
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 | class TCPState { public: virtual void Close(TCPConnection*) {} protected: void ChangeState(TCPConnection* t, TCPState* s); }; class TCPEstablished : public TCPState { public: static TCPState* Instance() { static TCPEstablished instance; return &instance; } virtual void Close(TCPConnection* t); }; class TCPListen : public TCPState { public: static TCPState* Instance() { static TCPListen instance; return &instance; } virtual void Close(TCPConnection* t); }; class TCPClosed : public TCPState { public: static TCPState* Instance() { static TCPClosed instance; return &instance; } virtual void Close(TCPConnection* t); }; | cs |
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 | TCPConnection::TCPConnection() { _state = TCPEstablished::Instance(); } void TCPConnection::Close() { _state->Close(this); } void TCPState::ChangeState(TCPConnection* t, TCPState* s) { t->ChangeState(s); } void TCPEstablished::Close(TCPConnection* t) { std::cout << typeid(this).name() << std::endl; ChangeState(t, TCPListen::Instance()); } void TCPListen::Close(TCPConnection* t) { std::cout << typeid(this).name() << std::endl; ChangeState(t, TCPClosed::Instance()); } void TCPClosed::Close(TCPConnection* t) { std::cout << typeid(this).name() << std::endl; ChangeState(t, TCPEstablished::Instance()); } | cs |
1 2 3 4 5 6 7 8 | void main() { TCPConnection a; a.Close(); a.Close(); a.Close(); a.Close(); } | cs |
TCPConnection 클래스는 위 도표의 Context 에 해당되며,
TCPState 는 TCPListen, TCPClosed, TCPEstablisthed 세 종류가 있음.
TCPConnection 은 초기값으로 TCPEstablisthed 를 가짐.
Context 인 TCPConnction 이 Close() 를 호출할 때마다 각 State 에 오버로드된 메소드는 state 를 다른 State 로 바꾸어줌.
그래서 main 을 실행하면 state 는 다음처럼 변하게 됨.
추가 설명
...
댓글 없음:
댓글 쓰기