C 設計模式之State模式

2022-04-01 18:17:24 字數 1362 閱讀 4630

這裡有兩個例子:

1、2、

關於此設計模式,有幾點概括:

context類包含抽象的state *_state成員變數,context類宣告為state類的frend(state至少會呼叫context類的changestate函式)。

state是在維護乙個狀態,這裡涉及到乙個關鍵問題,state怎麼可能不涉及到context裡的內容呢,比如,紅綠燈的實際例子裡,現在是紅燈狀態,且紅燈狀態有乙個60秒倒計時牌。這個60秒倒計時牌的顯示數字屬於context。如果我這樣做:

(先說實現的功能,進入紅燈狀態,顯示60秒倒計時,倒計時結束,則進入紅燈狀態)

1、紅燈狀態裡響應定時器,在定時器裡這樣寫,

context->countdown = 60 - sec;         //sec初始化為0,隨定時器相應增加。

context->updatewindow();                 //讓倒計時牌介面顯示重新整理

上面**沒什麼問題,問題主要在於耦合度太大,在state裡直接去修改了context裡的內容。應該怎樣寫,如下:

2、紅燈狀態裡響應定時器,在定時器裡這樣寫,

context->updatecountdownshow( count );          //updatecountdownshow是由context類提供的介面

總結下: 

state只負責維護狀態,而狀態下的行為應由context負責,做到狀態和行為分離,降低耦合度。

狀態模式好像就這麼簡單,有點需要注意的,就是每個狀態裡,有維護自身狀態的變數,比如上面進入紅燈狀態,倒計時變數應該清零,這裡可以有兩種做法,在changestate函式這個位置,1、切換狀態時,下乙個狀態全是用new出來的物件,利用建構函式做到進入到每個狀態時,狀態變數「乾乾淨淨」。切換到下乙個狀態前,先delete掉上乙個狀態。2、每個狀態在context中定義好,相當於全域性變數。這樣在上乙個狀態呼叫context->changestate之前,清掉本狀態相關狀態變數。

對new、delete很有信心的話用第一種方式少很多**(把建構函式裡的初始化變數提出來做為乙個函式,放倒上訴第2種的情況,好像就沒什麼差別:))。

2018/1/23補充:

1、使用c++11 智慧型指標,上面new delete的問題都沒有了。

2、上面兩個類存在交叉引用的問題,在乙個類的標頭檔案中包含另乙個標頭檔案(兩個類都這樣做),在某些情況下會導致編譯不過(state中肯定會呼叫context->changestate()這裡會編譯報錯,incomplte use of context)。整理下有可以這樣使用,在context標頭檔案裡,不包含state標頭檔案,宣告state類: class state;   在state類(及子類具體狀態類)中可以隨意包含context.h標頭檔案,使用ok!

設計模式之State模式

state模式類似於switch的多路分鐘功能 狀態模式的ulm圖 狀態模式用於改變目標物件的行為方式,隨著狀態變化目標程式從乙個轉到另乙個目標程式。package state public class creature private class forg implements state pri...

設計模式之state模式

狀態模式 state pattern 允許乙個物件在其內部狀態改變時改變它的行為。適用場景 一 乙個物件的行為取決於他的狀態,並且它必須在執行時根據狀態改變它 的行為 二 乙個操作中含有龐大的多分支條件語句,並且這些分支依賴於該物件的 狀態。優缺點 狀態模式的主要優點在於封裝了轉換規則,其缺點在於使...

C 設計模式之 狀態模式(State)

當乙個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類 狀態模式主要解決的是當控制乙個物件狀態轉換的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以複雜的判斷邏輯簡化。abstract class state class concretestatea...