【設計模式基礎】行為模式 - 8 -狀態(State)
1. 模式意圖
允許一個物件在其內部狀態改變時改變它的行為。物件看起來似乎是修改了它的類。
在很多情況下,一個物件的行為取決於一個或多個動態變化的屬性,這樣的屬性叫做狀態,這樣的物件叫做有狀態的物件。這樣的物件的狀態是從事先定義好的一系列值中取出的。當一個這樣的物件與外部事件產生互動時,其內部狀態就會改變,從而使得系統的行為也隨之發生變化。
適用性:
- 一個物件的行為取決於它的狀態,並且它必須在執行時根據狀態改變它的行為。
- 一個操作中含有龐大的多分支的條件語句,並且這些分支依賴於該物件的狀態。這個狀態通常用一個或多個列舉常量表示。通常,有多個操作包含這一相同的條件結構。State模式將每一個條件分之放入一個獨立的類中。這使得可以根據物件自身的情況將物件的狀態作為一個物件,這一物件可以不依賴於其他物件而獨立變化。
2. 模式定義
Context: 定義客戶感興趣的介面;維護一個ConcreteState子類的例項,這個例項定義當前狀態。
State: 定義一個介面以封裝與Context的一個特定狀態相關的行為。
ConcreteState:每一個子類實現一個與Context的一個狀態相關的行為。
協作:
- Context將與狀態相關的請求委託為當前的ConcreteState物件處理
- Context可將自身作為一個引數傳遞給處理該請求的狀態物件。這使得狀態物件在必要時可訪問Context
- Context是客戶使用的主要介面。客戶可用狀態物件來配置一個Context,一旦一個Context配置完畢,它的客戶不再需要直接與狀態物件打交道
- Context或ConcreteState子類都可以決定哪個狀態是另外哪一個的後繼者,以及是在何種條件下進行狀態轉換
優點:
- 它將與特定狀態相關的行為區域性化,並且將不同狀態的行為分隔開來
- 它使得狀態轉換顯式化
- State物件可被共享
缺點:
- 狀態模式的使用或增加系統類和物件的個數
- 狀態模式的結構和實現都比較複雜,如果使用不當將導致程式結構和程式碼的混亂
實現細節:
- 誰定義狀態轉換: state模式不指定哪一個參與者定義狀態轉換準則。如果該準則是固定的,那麼它們可以在Context中完全實現;然而若讓State子類自身指定它們的後繼狀態以及何時進行轉換,通常更靈活更合適。這需要Context增加一個介面,讓State物件顯式的設定Context的當前狀態。用這種方法分散轉換邏輯可以很容易地定義新的State子類來修改和擴充套件該邏輯。這樣做的缺點是,一個State子類至少擁有一個其他子類的資訊,這就在各子類之間產生了實現依賴。
- 建立和銷燬State物件: 究竟是(1)僅當需要State物件時才建立它們並隨後銷燬它們,還是(2)提前建立它們並且始終不銷燬它們。 當將要進入的狀態在執行時是不可知的,並且上下文不經常改變狀態時,第一種選擇較為可取。當狀態改變很頻繁時,第二張方法比較好,但是這種方法可能不太方便,因為Context必須儲存對所有可能會進入的那些狀態的引用。
3. 模式實現
3.1 C++實現State模式
class TCPOcterStream;
class TCPState;'
// Context
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::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);
}
// State
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*);
};
void TCPState::ChangeState(TCPConnection* t, TCPState* s)
{
t->ChangeState(s);
}
// Sub State - Established
class TCPEstablishd : public TCPState
{
public:
static TCPState* Instance();
virtual void Transmit(TCPConnection*, TCPOctetStream*);
virtual void Close(TCPConnection*);
};
void TCPEstablished::Transmit(TCPConnection* t, TCPOctetStream* o)
{
t->ProcessOctet(o);
}
void TCPEstablished::Close(TCPConnection* t)
{
// send FIN, receive ACK of FIN
// ... ...
ChangeState(t, TCPListen::Instance());
}
// Sub State - Closed
class TCPClosed : public TCPState
{
public:
static TCPState* Instance();
virtual void ActiveOpen(TCPConnection*);
virtual void PassiveOpen(TCPConnection*);
};
void TCPClosed::ActiveOpen(TCPConnection* t)
{
// send SYN, receive SYN, ACK, etc.
// ... ...
ChangeState(t, TCPEstablished::Instance());
}
void TCPClosed::PassiveOpen(TCPConnection* t)
{
// ... ...
ChangeState(t, TCPListen::Instance);
}
4. 模式應用
相關文章
- 設計模式--狀態模式State(行為型)設計模式
- 設計模式之狀態模式(State)設計模式
- 設計模式-狀態模式(State Pattern)設計模式
- 設計模式——20狀態模式(State)設計模式
- 設計模式之狀態模式---State Pattern設計模式
- C#設計模式系列:狀態模式(State)C#設計模式
- JAVA設計模式之 狀態模式【State Pattern】Java設計模式
- .NET下的狀態(State)模式 ------行為型模式模式
- 狀態模式(State)模式
- 設計模式之策略模式和狀態模式(strategy pattern & state pattern)設計模式
- 行為型設計模式 - 狀態模式詳解設計模式
- 狀態模式(State pattern)模式
- 設計模式(二十一)----行為型模式之狀態模式設計模式
- 23種設計模式 之 State模式(狀態模式)[C語言實現]設計模式C語言
- 轉載---Dephi狀態模式(State模式)模式
- 【設計模式基礎】行為模式 - 5 - 策略(Strategy)設計模式
- 行為型模式:狀態模式模式
- 設計模式-狀態模式設計模式
- 設計模式:狀態模式設計模式
- 【設計模式基礎】行為模式 - 7 - 迭代器(Iterator)設計模式
- 設計模式(十五)狀態模式設計模式
- 設計模式之——狀態模式設計模式
- javascript設計模式狀態模式JavaScript設計模式
- 設計模式(六):狀態模式設計模式
- 【設計模式基礎】行為模式 - 6 - 模板方法(Template Method)設計模式
- PHP 設計模式之狀態模式PHP設計模式
- 簡說設計模式——狀態模式設計模式
- python設計模式狀態模式Python設計模式
- 設計模式20之狀態模式設計模式
- 極簡設計模式-狀態模式設計模式
- GoLang設計模式14 - 狀態模式Golang設計模式
- Python設計模式-狀態模式Python設計模式
- Java設計模式之狀態模式Java設計模式
- 設計模式系列之「狀態模式」設計模式
- 使用C# (.NET Core) 實現狀態設計模式 (State Pattern)C#設計模式
- 詳解 state 狀態模式及在 C++ 設計模式程式設計中的使用例項C++設計模式程式設計
- 23種設計模式(七)-狀態設計模式設計模式
- 設計模式第八講-狀態模式設計模式