1.1. Intent ¶
κ°μ²΄μ λ΄λΆ μνκ° λ°λμμ λ κ°μ²΄μ νλμ λ°κΏ κ°μ²΄λ₯Ό νμ©νλ€. κ°μ²΄λ λ§μΉ κ°μ²΄μ ν΄λμ€κ° λ³κ²½λ κ²μ²λΌ λ³΄μΌ κ²μ΄λ€.
1.3. 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 μνλ₯Ό ꡬννλ€.
TCPConnection ν΄λμ€λ TCP 컀λ₯μ
μ νμ¬ μνλ₯Ό λνλ΄λ state κ°μ²΄λ₯Ό κ°μ§κ³ μλ€. (TCPState μλΈν΄λμ€μ μΈμ€ν΄μ€) TCPConnection μ μ΄ state κ°μ²΄μκ² λͺ¨λ μν-ꡬ체μ requestλ€μ μμ (delegate) νλ€. TCPConnection μ 컀λ₯μ
μ νΉμ μνμ λν λͺ
λ Ήλ€μ μννκΈ° μν΄ TCPState μλΈν΄λμ€ μΈμ€ν΄μ€λ₯Ό μ΄μ©νλ€.
컀λ₯μ
μ΄ μνλ₯Ό μ νν κ²½μ°, TCPConnection κ°μ²΄λ μ¬μ©νκ³ μλ state κ°μ²΄λ₯Ό λ°κΎΌλ€. μλ₯Ό λ€μ΄ 컀λ₯μ
μ΄ established μμ closed λ‘ λ°λλ κ²½μ° TCPConnection μ νμ¬μ TCPEstablished μΈμ€ν΄μ€λ₯Ό TCPClosed μΈμ€ν΄μ€λ‘ state κ°μ²΄λ₯Ό κ΅μ²΄νλ€.
1.4. Applicability ¶
λ€μκ³Ό κ°μ κ²½μ°μ StatePattern μ μ΄μ©νλ€.
- κ°μ²΄μ νμκ° κ°μ²΄μ μνμ μμ‘΄μ μΌλ. κ·Έλ¦¬κ³ κ°μ²΄κ° run-time μμ μνμ λ°λΌ νμλ₯Ό λ°κΎΈμ΄μΌ ν κ²½μ°.
- κ°μ²΄μ μνμ λν μ²λ¦¬λ₯Ό μν΄ κ΅¬ννλ λ€μ€ 쑰건 μ μ΄λ¬Έμ΄ κ±°λν΄μ§ κ²½μ°. μ΄ μνλ€μ μΌλ°μ μΌλ‘ νλλ κ·Έ μ΄μμ μ΄κ±°ν μμλ€λ‘ ννλλ€. μ’
μ’
μ¬λ¬ λͺ
λ Ήλ€μ κ°μ²΄ μνμ λ°λ₯Έ μ²λ¦¬λ₯Ό μν΄ λΉμ·ν μ νμ 쑰건 μ μ΄μ κ΄λ ¨ν μ½λλ₯Ό κ°μ§κ² λλ€. StatePattern μ κ°κ°μ 쑰건λΆκΈ°μ λ€μ ν΄λμ€λ‘ λΆλ¦¬μν¨λ€. μ΄λ κ°μ²΄μ μνλ€μ λ€λ₯Έ κ°μ²΄λ‘λΆν° λ€μνκ² λ
립μ μΌ μ μλ, κ³ μ μ κΆλ¦¬λ₯Ό κ°μ§λ κ°μ²΄λ‘μ μ·¨κΈνλλ‘ ν΄μ€λ€.
1.6. Participants ¶
- Context (TCPConnection)
- ν΄λΌμ΄μΈνΈλ€μ΄ μνλ μΈν°νμ΄μ€λ₯Ό μ μνλ€.
- νμ¬ μνλ₯Ό μ μνλ ConcreteState μλΈν΄λμ€μ μΈμ€ν΄μ€λ₯Ό κ°μ§λ€.
- ν΄λΌμ΄μΈνΈλ€μ΄ μνλ μΈν°νμ΄μ€λ₯Ό μ μνλ€.
- State (TCPState)
- Context μ νΉμ μνμ κ΄λ ¨λ νμλ€μ μΊ‘μν νκΈ° μν κ΄λ ¨ μΈν°νμ΄μ€λ₯Ό μ μνλ€.
- Context μ νΉμ μνμ κ΄λ ¨λ νμλ€μ μΊ‘μν νκΈ° μν κ΄λ ¨ μΈν°νμ΄μ€λ₯Ό μ μνλ€.
- ConcreteState subclass (TCPEstablished, TCPListen, TCPClosed)
- κ°κ°μ μλΈν΄λμ€λ€μ Contextμ μνλ€κ³Ό κ΄λ ¨λ νμλ€μ ꡬννλ€.
- κ°κ°μ μλΈν΄λμ€λ€μ Contextμ μνλ€κ³Ό κ΄λ ¨λ νμλ€μ ꡬννλ€.
1.7. Collaborations ¶
- Contextλ μν-ꡬ체μ requestλ€μ νμ¬μ ConcreteState κ°μ²΄μ μμνλ€.
- contextλ requestλ₯Ό λ€λ£¨λ State κ°μ²΄μκ² μΈμλ‘μ μκΈ° μμ μ λκΈΈ μ μλ€. μ΄λ νμν κ²½μ° State κ°μ²΄λ€λ‘ νμ¬κΈ context μ μ κ·Όν μ μλλ‘ ν΄μ€λ€.
- Contextλ ν΄λΌμ΄μΈνΈμ μ£Όλ μΈν°νμ΄μ€μ΄λ€. ν΄λΌμ΄μΈνΈλ€μ State κ°μ²΄λ€κ³Ό ν¨κ» context λ₯Ό μ€μ ν μ μλ€. μΌλ¨ contextκ° μ€μ λλ©΄, context μ ν΄λΌμ΄μΈνΈλ State κ°μ²΄λ€μ μ§μ μ μΌλ‘ λ€λ£° νμκ° μλ€.
- Context λ ConcreteState μλΈν΄λμ€λ μν©μ λ°λΌ stateλ₯Ό κ²°μ ν μ μλ€.
1.8. Consequences ¶
StatePatternμ λ€μκ³Ό κ°μ κ²°κ³Όλ₯Ό κ°μ§λ€.
- It localizes state-specific behavior and partitions bahavior for different states.
- It makes state transitions explicit.
- State objects can be shared.
1.9. Implementation ¶
- Who defines the state transitions?
- A table-based alternative.
- Creating and destroying State objects.
- Using dynamic inheritance.
1.10. 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 μλΈν΄λμ€λ€μ΄λ€.
1.11. 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 μΈν°νμ΄μ€μ λν μ€λͺ
μ΄λ€.
Coplien's Envelope-Letter idiom Cop92 λ State μ κ΄λ ¨λμ΄μλ€. Envelope-Letter λ run-time μμ κ°μ²΄μ ν΄λμ€λ₯Ό μ ννλ λ°©λ²μ΄λ€. StatePattern μ λ ꡬ체μ μ΄λ©°, κ°μ²΄μ μνμ κ·Έ νμκ° μμ‘±μ μΌλμ λ€λ£¨λ λ°©λ²μ μ΄μ μ λ§μΆλ€.
1.12. Related Patterns ¶
- FlyweightPattern μ Stateκ°μ²΄λ€μ΄ μΈμ μ΄λ»κ² 곡μ λλμ§ νννλ€.
- Stateκ°μ²΄λ μ’
μ’
SingletonPattern μΌλ‘ ꡬνλλ€.