[设计模式][c++]状态切换模式
轉(zhuǎn)自:http://blog.csdn.net/yongh701/article/details/49154439
?
狀態(tài)模式也是設(shè)計模式的一種,這種設(shè)計模式思想不復(fù)雜,就是實現(xiàn)起來的代碼有點復(fù)雜。主要出現(xiàn)在類傳遞參數(shù)上,尤其是C++這種不能直接類間互相調(diào)用都語言,實現(xiàn)狀態(tài)模式更難,當(dāng)然,一切設(shè)計模式都是為了更簡短的主函數(shù)。
狀態(tài)模式是當(dāng)一個對象的內(nèi)在狀態(tài)改變時允許改變其行為,這個對象看起來像是改變了其類,主要解決的是當(dāng)控制一個對象狀態(tài)轉(zhuǎn)換的條件表達式過于復(fù)雜時的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同的一系列類當(dāng)中,可以把復(fù)雜的邏輯判斷簡單化。主要有以下三種角色:
1、上下文環(huán)境(Context):它定義了客戶程序需要的接口并維護一個具體狀態(tài)角色的實例,將與狀態(tài)相關(guān)的操作委托給當(dāng)前的Concrete State對象來處理。
2、抽象狀態(tài)(State):定義一個接口以封裝使用上下文環(huán)境的的一個特定狀態(tài)相關(guān)的行為。
3、具體狀態(tài)(Concrete State):實現(xiàn)抽象狀態(tài)定義的接口。
說是這樣的意思:
舉個例子來說明吧,如下圖:
現(xiàn)在要求再主函數(shù)中,直接一行代碼context->switch_state();從狀態(tài)A切到狀態(tài)B。
這里利用狀態(tài)模式來實現(xiàn),具體狀態(tài)就是狀態(tài)A與狀態(tài)B,然后上下文存在一個“轉(zhuǎn)換狀態(tài)”的方法。之后狀態(tài)A與狀態(tài)B共同接口就是抽象狀態(tài)State。具體實現(xiàn)代碼如下:
?
[cpp]?view plaincopy print?
運行結(jié)果如下圖:
?
可以看到,在主函數(shù)中,只是初始化了上下文,然而不停調(diào)用上下文的switch_state()方法,卻在兩個具體狀態(tài)A與B之間跳轉(zhuǎn)。然而,同樣的一句switch_state()有著不同實現(xiàn),打印的內(nèi)容是不同。
上述代碼還有C++的特色,各個具體狀態(tài)中,所對應(yīng)轉(zhuǎn)換狀態(tài)方法,只能在類外實現(xiàn),而不能在直接在StateA與StateB里面實現(xiàn)。因為C++不像Java,Java編譯的時候一次性把所有東西讀進去。C++是見一行讀一行。這里Context類用到State,StateA與StateB用到了Context,類間相互調(diào)用在C++中是不行的。
同時,注意在上下文類Context的構(gòu)造類,對各個具體狀態(tài)初始化,也就是注冊各個具體狀態(tài)到上下文,否則編譯是過了,卻在程序中出現(xiàn)空指針。
那么這種狀態(tài)模式到底有什么呢?這里用一道2011年下半年的軟件設(shè)計師軟考題目再來說明:
題目是這樣的:
某大型商場內(nèi)安裝了多個簡易的紙巾售賣機,自動出售2元錢一包的紙巾,且每次僅售出一包紙巾,紙巾售賣機的狀態(tài)圖如圖5-1所示:
?
采用狀態(tài)(State)模式來實現(xiàn)該紙巾售賣機,得到如圖5-2所示的類圖,其中類State為抽象類,定義了投幣、退幣、出紙巾等方法接口。類SoldOutState、NoQuarterState、HasQuarterState、SoldState分別對應(yīng)圖5-1紙巾售賣機的4種狀態(tài)。售出紙巾、紙巾售賣、買有投幣、有2元錢。
這里很顯然,如果不用狀態(tài)模式,會產(chǎn)生大量的if...else語句,代碼將很不容易改變,,難以拓展。狀態(tài)轉(zhuǎn)換隱藏在條件語句中,所以并不明顯未來加入的代碼可能導(dǎo)致bug。
那么用狀態(tài)模式,先來分析一下,這里具體狀態(tài)有4個,分別對應(yīng)4個類,TissueMachine類就是開放給主函數(shù)的上下文,而用戶能夠操作的地方,有3個,一個是投幣、一個是退幣,另一個是按“出紙巾”,這是上下文TissueMachine能給主函數(shù)調(diào)用的方法就這三個。而沒有提到的售出方法dispense,是上下文自身內(nèi)部的狀態(tài)裝換,因此只在售出紙巾這個狀態(tài)中實現(xiàn)這個方法。不過,由于抽象狀態(tài)State定義了這4個方法的接口,因此,4個具體狀態(tài)都要有這4個方法,當(dāng)然具體實現(xiàn)因狀態(tài)不同而不同,具體代碼如下:
?
[cpp]?view plaincopy print?
運行結(jié)果如下:
?
這里設(shè)置紙巾機一開始僅有1個紙巾,分別做不同的測試,可見紙巾自動售貨機有不同的響應(yīng)。
轉(zhuǎn)載于:https://www.cnblogs.com/lyggqm/p/7064565.html
總結(jié)
以上是生活随笔為你收集整理的[设计模式][c++]状态切换模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: go 数据类型和操作符
- 下一篇: MVC之排球比赛计分程序 ——(二)架构