[[TableOfContents]] = State = == Intent == ê°ì²´ì˜ ë‚´ë¶€ ìƒíƒœê°€ ë°”ë€Œì—ˆì„ ë•Œ ê°ì²´ì˜ í–‰ë™ì„ 바꿀 ê°ì²´ë¥¼ 허용한다. ê°ì²´ëŠ” 마치 ê°ì²´ì˜ í´ëž˜ìŠ¤ê°€ ë³€ê²½ëœ ê²ƒì²˜ëŸ¼ ë³´ì¼ ê²ƒì´ë‹¤. == Also Known As == Objects for States == Motivation == ë„¤íŠ¸ì›Œí¬ ì»¤ë„¥ì…˜ì„ ë‚˜íƒ€ë‚´ëŠ” TCPConnection ë¼ëŠ” í´ëž˜ìŠ¤ë¥¼ ìƒê°í•´ë³´ìž. TCPConnection ê°ì²´ëŠ” ì—¬ëŸ¬ê°€ì§€ì˜ ìƒíƒœì¤‘ 하나 ì¼ ìˆ˜ 있다. (Established, Listening, Closed). TCPConnection ê°ì²´ê°€ 다른 ê°ì²´ë¡œë¶€í„° request를 ë°›ì•˜ì„ ë•Œ, TCPConnection ì€ í˜„ìž¬ì˜ ìƒíƒœì— ë”°ë¼ ë‹¤ë¥´ê²Œ ì‘ë‹µì„ í•˜ê²Œ ëœë‹¤. 예를 들어 'Open' ì´ë¼ëŠ” requestì˜ íš¨ê³¼ëŠ” í˜„ìž¬ì˜ ìƒíƒœê°€ Closed ì´ëƒ Established ì´ëƒì— ë”°ë¼ ë‹¤ë¥´ë‹¤. StatePatternì€ TCPConnection ì´ ê° ìƒíƒœì— 따른 다른 í–‰ìœ„ë“¤ì„ í‘œí˜„í• ìˆ˜ 있는 ë°©ë²•ì— ëŒ€í•´ 설명한다. StatePattern ì˜ ì£¼ëœ ì•„ì´ë””어는 ë„¤íŠ¸ì›Œí¬ ì»¤ë„¥ì…˜ì˜ ìƒíƒœë¥¼ 나타내는 TCPState ì¶”ìƒí´ëž˜ìŠ¤ë¥¼ ë„입하는ë°ì— 있다. TCPState í´ëž˜ìŠ¤ëŠ” ê°ê° 다른 ìƒíƒœë“¤ì„ 표현하는 ëª¨ë“ í´ëž˜ìŠ¤ë“¤ì— ëŒ€í•œ ì¼ë°˜ì ì¸ ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì •ì˜í•œë‹¤. TCPStateì˜ ì„œë¸Œí´ëž˜ìŠ¤ëŠ” ìƒíƒœ-구체ì í–‰ìœ„ë“¤ì„ êµ¬í˜„í•œë‹¤. 예를 들어 TCPEstablished 는 TCPConnection ì˜ Established ìƒíƒœë¥¼, TCPClosed 는 TCPConnection ì˜ Closed ìƒíƒœë¥¼ 구현한다. http://zeropage.org/~reset/zb/data/state_eg.gif TCPConnection í´ëž˜ìŠ¤ëŠ” TCP ì»¤ë„¥ì…˜ì˜ í˜„ìž¬ ìƒíƒœë¥¼ 나타내는 state ê°ì²´ë¥¼ ê°€ì§€ê³ ìžˆë‹¤. (TCPState 서브í´ëž˜ìŠ¤ì˜ ì¸ìŠ¤í„´ìŠ¤) TCPConnection ì€ ì´ state ê°ì²´ì—게 ëª¨ë“ ìƒíƒœ-구체ì requestë“¤ì„ ìœ„ìž„ (delegate) 한다. TCPConnection ì€ ì»¤ë„¥ì…˜ì˜ íŠ¹ì • ìƒíƒœì— 대한 ëª…ë ¹ë“¤ì„ ìˆ˜í–‰í•˜ê¸° 위해 TCPState 서브í´ëž˜ìФ ì¸ìŠ¤í„´ìŠ¤ë¥¼ ì´ìš©í•œë‹¤. ì»¤ë„¥ì…˜ì´ ìƒíƒœë¥¼ ì „í™˜í• ê²½ìš°, TCPConnection ê°ì²´ëŠ” ì‚¬ìš©í•˜ê³ ìžˆëŠ” state ê°ì²´ë¥¼ 바꾼다. 예를 들어 ì»¤ë„¥ì…˜ì´ established ì—서 closed 로 바뀌는 경우 TCPConnection ì€ í˜„ìž¬ì˜ TCPEstablished ì¸ìŠ¤í„´ìŠ¤ë¥¼ TCPClosed ì¸ìŠ¤í„´ìŠ¤ë¡œ state ê°ì²´ë¥¼ êµì²´í•œë‹¤. == Applicability == 다ìŒê³¼ ê°™ì€ ê²½ìš°ì— StatePattern ì„ ì´ìš©í•œë‹¤. * ê°ì²´ì˜ 행위가 ê°ì²´ì˜ ìƒíƒœì— ì˜ì¡´ì ì¼ë•Œ. ê·¸ë¦¬ê³ ê°ì²´ê°€ run-time ì‹œì— ìƒíƒœì— ë”°ë¼ í–‰ìœ„ë¥¼ 바꾸어야 í• ê²½ìš°. * ê°ì²´ì˜ ìƒíƒœì— 대한 처리를 위해 구현하는 다중 ì¡°ê±´ ì œì–´ë¬¸ì´ ê±°ëŒ€í•´ì§ˆ 경우. ì´ ìƒíƒœë“¤ì„ ì¼ë°˜ì 으로 하나나 ê·¸ ì´ìƒì˜ 열거형 ìƒìˆ˜ë“¤ë¡œ 표현ëœë‹¤. 종종 여러 ëª…ë ¹ë“¤ì€ ê°ì²´ ìƒíƒœì— 따른 처리를 위해 비슷한 ìœ í˜•ì˜ ì¡°ê±´ ì œì–´ì™€ ê´€ë ¨í•œ 코드를 가지게 ëœë‹¤. StatePattern ì€ ê°ê°ì˜ 조건분기ì ë“¤ì„ í´ëž˜ìŠ¤ë¡œ 분리시킨다. ì´ëŠ” ê°ì²´ì˜ ìƒíƒœë“¤ì„ 다른 ê°ì²´ë¡œë¶€í„° 다양하게 ë…립ì ì¼ ìˆ˜ 있는, ê³ ìœ ì˜ ê¶Œë¦¬ë¥¼ 가지는 ê°ì²´ë¡œì„œ 취급하ë„ë¡ í•´ì¤€ë‹¤. == Structure == http://zeropage.org/~reset/zb/data/state.gif == Participants == * Context (TCPConnection) * í´ë¼ì´ì–¸íŠ¸ë“¤ì´ ì›í•˜ëŠ” ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì •ì˜í•œë‹¤. * 현재 ìƒíƒœë¥¼ ì •ì˜í•˜ëŠ” ConcreteState 서브í´ëž˜ìŠ¤ì˜ ì¸ìŠ¤í„´ìŠ¤ë¥¼ 가진다. * State (TCPState) * Context ì˜ íŠ¹ì • ìƒíƒœì™€ ê´€ë ¨ëœ í–‰ìœ„ë“¤ì„ ìº¡ìŠí™” 하기 위한 ê´€ë ¨ ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì •ì˜í•œë‹¤. * ConcreteState subclass (TCPEstablished, TCPListen, TCPClosed) * ê°ê°ì˜ 서브í´ëž˜ìŠ¤ë“¤ì€ Contextì˜ ìƒíƒœë“¤ê³¼ ê´€ë ¨ëœ í–‰ìœ„ë“¤ì„ êµ¬í˜„í•œë‹¤. == Collaborations == * Context는 ìƒíƒœ-구체ì requestë“¤ì„ í˜„ìž¬ì˜ ConcreteState ê°ì²´ì— 위임한다. * context는 request를 다루는 State ê°ì²´ì—게 ì¸ìžë¡œì„œ ìžê¸° ìžì‹ ì„ ë„˜ê¸¸ 수 있다. ì´ëŠ” 필요한 경우 State ê°ì²´ë“¤ë¡œ 하여금 context ì— ì ‘ê·¼í• ìˆ˜ 있ë„ë¡ í•´ì¤€ë‹¤. * Context는 í´ë¼ì´ì–¸íŠ¸ì˜ ì£¼ëœ ì¸í„°íŽ˜ì´ìФì´ë‹¤. í´ë¼ì´ì–¸íŠ¸ë“¤ì€ State ê°ì²´ë“¤ê³¼ 함께 context 를 ì„¤ì •í• ìˆ˜ 있다. ì¼ë‹¨ contextê°€ ì„¤ì •ë˜ë©´, context ì˜ í´ë¼ì´ì–¸íŠ¸ëŠ” State ê°ì²´ë“¤ì„ ì§ì ‘ì 으로 다룰 필요가 없다. * Context 나 ConcreteState 서브í´ëž˜ìŠ¤ëŠ” ìƒí™©ì— ë”°ë¼ state를 ê²°ì •í• ìˆ˜ 있다. == Consequences == StatePatternì€ ë‹¤ìŒê³¼ ê°™ì€ ê²°ê³¼ë¥¼ 가진다. 1. It localizes state-specific behavior and partitions bahavior for different states. * It makes state transitions explicit. * State objects can be shared. == Implementation == 1. Who defines the state transitions? * A table-based alternative. * Creating and destroying State objects. * Using dynamic inheritance. == Sample Code == 다ìŒì˜ ì˜ˆì œëŠ” 앞서 Motivation ì—서 ì–¸ê¸‰í–ˆì—ˆë˜ TCP ì»¤ë‚µì…˜ì— ëŒ€í•œ C++ ì½”ë“œì˜ ì˜ˆì´ë‹¤. ì´ ì—ì œëŠ” TCP í”„ë¡œí† ì½œì— ëŒ€í•´ 단순화 시킨 것ì´ë¯€ë¡œ, TCP ì»¤ë„¥ì…˜ë“¤ì˜ ëª¨ë“ ìƒíƒœë‚˜ í”„í† í† ì½œ ì „ì²´ë¥¼ 설명하지 않는다. (ì´ ì˜ˆì œëŠ” Lynch 와 Rose [LR93] ì— ì˜í•´ ì„¤ëª…ëœ TCP 커넥션 í”„ë¡œí† ì½œì— ê¸°ì´ˆí•œ 것ì´ë‹¤) ì¼ë‹¨, 우리는 TCPConnection í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•œë‹¤. TCPConnection ì€ ë°ì´í„°ë¥¼ ì „ë‹¬í•˜ê³ ìƒíƒœ ì „í™˜ì„ ìœ„í•œ request를 다루는 ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì œê³µí•œë‹¤. {{{~cpp class TCPOctectStream; class TCPState; class TCPConnection { public: TCPConnection (); void ActiveOpen (); void PassiveOpen (); void Close (); void Send (); void Acknowledge (); void Synchronize (); void ProcessOctet (TCPOctetStream* ); private: friend class TCPState; void ChangeState (TCPState* ); private: TCPState* _state; }; }}} TCPConnection ì€ _state 멤버변수를 ì´ìš©, TCPState ì˜ ì¸ìŠ¤í„´ìŠ¤ë¥¼ ìœ ì§€í•œë‹¤. TCPState í´ëž˜ìŠ¤ëŠ” TCPConnection ì˜ ìƒíƒœ-ì „í™˜ ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ 중복하여 가진다. ê°ê°ì˜ TCPState ëª…ë ¹ë“¤ì€ TCPConnection ì¸ìŠ¤í„´ìŠ¤ë¥¼ ì¸ìžë¡œì„œ 취하며, TCPState 로 하여금 TCPConnection 으로부터 ë°ì´í„°ë¥¼ ì ‘ê·¼í•˜ê±°ë‚˜ 현재 ì»¤ë„¥ì…˜ì˜ ìƒíƒœë¥¼ ì „í™˜í• ìˆ˜ 있ë„ë¡ í•œë‹¤. {{{~cpp class TCPState { public: virtual void Transmit (TCPConnection* , TCPOctetStream* ): virtual void ActiveOpen (TCPConnection* ); virtual void PassiveOpen (TCPConnection* ); virtual void Close (TCPConnection* ); virtual void Synchronize (TCPConnection* ); virtual void Acknowledge (TCPConnection* ); virtual void Send (TCPConnection* ); protected: void ChangeState (TCPConnection* , TCPState* ); }; }}} TCPConnection ì€ ìƒíƒœ-구체ì request들으 TCPState ì¸ìŠ¤í„´ìŠ¤ì¸ _state ì— ìœ„ìž„í•œë‹¤. TCPConnection ì€ ë˜í•œ ì´ ë³€ìˆ˜ë¥¼ 새로운 TCPState 로 ì „í™˜í•˜ëŠ” ëª…ë ¹ì„ ì œê³µí•œë‹¤. TCPConnection ì˜ ìƒì„±ìžëŠ” _state를 TCPClosed ìƒíƒœë¡œ 초기화한다. (í›„ì— ì •ì˜ëœë‹¤.) {{{~cpp TCPConnection::TCPConnection () { _state = TCPClosed::Instance (); } void TCPConnection::ChangeState (TCPState* s) { _state = s; } void TCPConnection::ActiveOpen () { _state->ActiveOpen (this); } void TCPConnection::PassiveOpen () { _state->PassiveOpen (this); } void TCPConnection::Close () { _state->Close (this); } void TCPConnection::Acknowledge () { _state->Acknowledge (this); } void TCPConnection::Synchronize () { _state->Synchronize (this); } }}} TCPState 는 ìœ„ìž„ë°›ì€ ëª¨ë“ request ì— ëŒ€í•œ 기본 행위를 구현한다. TCPState는 ë˜í•œ ChnageState ëª…ë ¹ìœ¼ë¡œì¨ TCPConnection ì˜ ìƒíƒœë¥¼ ì „í™˜í• ìˆ˜ 있다. TCPState 는 TCPConnection ì˜ friend class 로 ì„ ì–¸ë˜ì–´ì§„다. ì´ë¡œì¨ TCPState 는 TCPConnection ì˜ ëª…ë ¹ë“¤ì— ëŒ€í•œ ì ‘ê·¼ ê¶Œí•œì„ ê°€ì§„ë‹¤. {{{~cpp void TCPState::Transmit (TCPConnection*, TCPOctetStream* ) { } void TCPState::ActiveOpen (TCPConnection* ) { } void TCPState::PassiveOpen (TCPConnection* ) { } void TCPState::Close (TCPConnection* ) { } void TCPState::Synchronize (TCPConnection* ) { } void TCPState::ChangeState (TCPConnection* t, TCPState* s) { t->ChangeState (s); } }}} TCPStateì˜ ì„œë¸Œí´ëž˜ìŠ¤ë“¤ì€ ìƒíƒœ-구체ì í–‰ìœ„ë“¤ì„ êµ¬í˜„í•œë‹¤. TCP ì»¤ë„¥ì…˜ì€ ë‹¤ì–‘í•œ ìƒíƒœì¼ 수 있다. Established, Listen, Closed 등등. ê·¸ë¦¬ê³ ê° ìƒíƒœë“¤ì— 대한 TCPState ì˜ ì„œë¸Œí´ëž˜ìŠ¤ë“¤ì´ ìžˆë‹¤. 여기서는 3ê°œì˜ ì„œë¸Œí´ëž˜ìŠ¤ë“¤ì„ ë‹¤ë£° 것ì´ë‹¤. (TCPEstablished, TCPListen, TCPClosed) {{{~cpp class TCPEstablished : public TCPState { public: static TCPState* Instance (); virtual void Transmit (TCPConnection* , TCPOctetStream* ); virtual void Close (TCPConnection* ); }; class TCPListen : public TCPState { public: static TCPState* Instance (); virtual void Send (TCPConnection* ); // ... }; class TCPClosed : public TCPState { public: static TCPState* Instance (); virtual void ActiveOpen (TCPConnection* ); virtual void PassiveOpen (TCPConnection* ); // ... }; }}} TCPState 서브í´ëž˜ìŠ¤ëŠ” ë‚´ë¶€ ìƒíƒœë¥¼ 가지지 않는다, 그러므로 TCPState는 ê³µìœ ë 수 ìžˆê³ , ê°ê° 단지 í•˜ë‚˜ì˜ ì¸ìŠ¤í„´ìŠ¤ë§Œì´ ìš”êµ¬ë˜ì–´ì§„다. ì´ TCPState 서브í´ëž˜ìŠ¤ì˜ ê°ê°ì˜ ìœ ì¼í•œ ì¸ìŠ¤í„´ìŠ¤ë“¤ì€ ì •ì í•¨ìˆ˜ì¸ Instance 로 얻어진다. (TCPState 서브í´ëž˜ìŠ¤ëŠ” Singleton 으로 만들어진다.) ê°ê°ì˜ TCPState 서브í´ëž˜ìŠ¤ëŠ” 해당 ìƒíƒœì— 알맞는 request ì— ëŒ€í•œ ìƒíƒœ-구체ì í–‰ìœ„ë“¤ì„ êµ¬í˜„í•œë‹¤. {{{~cpp void TCPClosed::ActiveOpen (TCPConnection* t) { // send SYN, receive SYN, ACK, etc. ChangeState (t, TCPEstablished::Instance ()); } void TCPClosed::PassiveOpen (TCPConnection* t) { ChangeState (t, TCPListen::Instance ()); } void TCPEstablished::Close (TCPConnection* t) { // send FIN, receive ACK of FIN ChangeState (t, TCPListen::Instance ()); } void TCPEstablished::Transmit (TCPConnection* t, TCPOctetStream* o) { t->ProcessOctet (o); } void TCPListen::Send (TCPConnection* t) { // send SYN, receive SYN, ACK, etc. ChangeState (t, TCPEstablished::Instance ()); } }}} ìƒíƒœ-구체ì ìž‘ì—…ë“¤ì´ ìˆ˜í–‰ëœ ë’¤, ì´ ëª…ë ¹ë“¤ì€ TCPConnection ì˜ ìƒíƒœë¥¼ ì „í™˜í•˜ê¸° 위해 ChangeState ëª…ë ¹ì„ í˜¸ì¶œí•œë‹¤. TCPConnection ì€ TCP 커넥션 í”„ë¡œí† ì½œì— ëŒ€í•´ 모른다. TCPì— ëŒ€í•œ ê°ê°ì˜ ìƒíƒœì „환과 í–‰ë™ë“¤ì„ ì •ì˜í•˜ëŠ” ê²ƒì€ TCPState 서브í´ëž˜ìŠ¤ë“¤ì´ë‹¤. == Known Uses == Johnson an Zweig [JZ91] ì€ StatePattern ê³¼ TCP 커넥션 í”„ë¡œí† ì½œë¡œ 어플리케ì´ì…˜ì˜ íŠ¹ì„±ì„ ë‚˜íƒ€ë‚¸ë‹¤. ëŒ€ë¶€ë¶„ì˜ ëŒ€ì¤‘ì ì¸ ìƒí˜¸ìž‘ìš©ì ì¸ ë“œë¡œìž‰ í”„ë¡œê·¸ëž¨ë“¤ì€ ì§ì ‘ 조작하여 ëª…ë ¹ì„ ìˆ˜í–‰í•˜ëŠ” 'tool' ì„ ì œê³µí•œë‹¤. 예를 들어, line-drawing tool ì€ ì‚¬ìš©ìžê°€ í´ë¦ & ë“œë ˆê·¸ 함으로서 새 ì„ ì„ ê·¸ë¦´ 수 있ë„ë¡ í•´ì¤€ë‹¤. selection tool ì€ ì‚¬ìš©ìžê°€ ë„í˜•ì„ ì„ íƒí• 수 있게 해준다. 보통 ì´ëŸ¬í•œ íˆ´ë“¤ì˜ palette (ì¼ì¢…ì˜ ë„구ìƒìž 패ë„)를 ì œê³µí•œë‹¤. 사용ìžëŠ” ì´ëŸ¬í•œ í–‰ë™ì„ 'toolì„ ì„ íƒí•œ ë’¤ ì„ íƒí•œ toolì„ ì´ìš©í•œë‹¤' ë¼ê³ ìƒê°í•œë‹¤. 하지만, ì‹¤ì œë¡œëŠ” editor ì˜ í–‰ìœ„ê°€ 현재 ì„ íƒí•œ tool로 ì „í™˜ë˜ëŠ” 것ì´ë‹¤. drawing tool ì´ í™œì„±í™” ë˜ì—ˆì„ 때 우리는 ë„í˜•ì„ ê·¸ë¦¬ê³ selection tool ì´ í™œì„±í™” ë˜ì—ˆì„ 때 ë„í˜•ì„ ì„ íƒí• 수 있는 ì‹ì´ë‹¤. 우리는 현재 ì„ íƒëœ tool ì— ë”°ë¥¸ editor ì˜ í–‰ìœ„ë¥¼ ì „í™˜ì‹œí‚¤ëŠ” ë¶€ë¶„ì— ëŒ€í•´ StatePattern ì„ ì´ìš©í• 수 있다. 툴-구체ì 행위를 구현하는 서브í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•˜ëŠ” ê³³ì— ëŒ€í•´ Tool ì¶”ìƒ í´ëž˜ìŠ¤ë¥¼ ì •ì˜í• 수 있다. drawing editor 는 currentTool ê°ì²´ë¥¼ 가지며, request를 ì´ ê°ì²´ì— 위임시킨다. 사용ìžê°€ 새 tool를 골ëžì„ 때, drawing editor 는 행위를 ì „í™˜í•´ì•¼ 하므로 ë”°ë¼ì„œ ì´ ê°ì²´ëŠ” êµì²´ëœë‹¤. ì´ ë°©ë²•ì€ HowDraw [Joh92]와 Unidraw [VL90] drawing editor í”„ë ˆìž„ì›Œí¬ì— ì´ìš©ë˜ì—ˆë‹¤. ì´ëŠ” í´ë¼ì´ì–¸íŠ¸ë¡œ 하여금 새로운 ì¢…ë¥˜ì˜ toolë“¤ì„ ì‰½ê²Œ ì •ì˜í• 수 있ë„ë¡ í•´ì¤€ë‹¤. HowDraw ì—서 DrawingController í´ëž˜ìŠ¤ëŠ” currentTool ê°ì²´ì—게 request를 넘긴다. UniDrawì—서는 ê°ê° Viewer 와 Tool í´ëž˜ìŠ¤ê°€ ì´ì™€ ê°™ì€ ê´€ê³„ë¥¼ 가진다. 다ìŒì˜ í´ëž˜ìФ 다ì´ì–´ê·¸ëž¨ì€ Tool ê³¼ DrawingController ì¸í„°íŽ˜ì´ìŠ¤ì— ëŒ€í•œ 설명ì´ë‹¤. http://zeropage.org/~reset/zb/data/state012.gif Coplien's Envelope-Letter idiom [Cop92] 는 State 와 ê´€ë ¨ë˜ì–´ìžˆë‹¤. Envelope-Letter 는 run-time ì‹œì— ê°ì²´ì˜ í´ëž˜ìŠ¤ë¥¼ ì „í™˜í•˜ëŠ” 방법ì´ë‹¤. StatePattern ì€ ë” êµ¬ì²´ì ì´ë©°, ê°ì²´ì˜ ìƒíƒœì— ê·¸ 행위가 ì˜ì¡±ì ì¼ë•Œì— 다루는 ë°©ë²•ì— ì´›ì ì„ ë§žì¶˜ë‹¤. == Related Patterns == * FlyweightPattern ì€ Stateê°ì²´ë“¤ì´ ì–¸ì œ 어떻게 ê³µìœ ë˜ëŠ”ì§€ 표현한다. * Stateê°ì²´ëŠ” 종종 SingletonPattern 으로 구현ëœë‹¤. ---- ["패턴분류"]