狀態(tài)模式將一個(gè)對(duì)象在不同狀態(tài)下的不同行為封裝在一個(gè)個(gè)狀態(tài)類中,通過設(shè)置不同的狀態(tài)對(duì)象可以讓環(huán)境對(duì)象擁有不同的行為,而狀態(tài)轉(zhuǎn)換的細(xì)節(jié)對(duì)于客戶端而言是透明的,方便了客戶端的使用。在實(shí)際開發(fā)中,狀態(tài)模式具有較高的使用頻率,在工作流和游戲開發(fā)中狀態(tài)模式都得到了廣泛的應(yīng)用,例如公文狀態(tài)的轉(zhuǎn)換、游戲中角色的升級(jí)等。
狀態(tài)模式的主要優(yōu)點(diǎn)如下:
(1) 封裝了狀態(tài)的轉(zhuǎn)換規(guī)則,在狀態(tài)模式中可以將狀態(tài)的轉(zhuǎn)換代碼封裝在環(huán)境類或者具體狀態(tài)類中,可以對(duì)狀態(tài)轉(zhuǎn)換代碼進(jìn)行集中管理,而不是分散在一個(gè)個(gè)業(yè)務(wù)方法中。
(2) 將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類中,只需要注入一個(gè)不同的狀態(tài)對(duì)象即可使環(huán)境對(duì)象擁有不同的行為。
(3) 允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體,而不是提供一個(gè)巨大的條件語句塊,狀態(tài)模式可以讓我們避免使用龐大的條件語句來將業(yè)務(wù)方法和狀態(tài)轉(zhuǎn)換代碼交織在一起。
(4) 可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)。
狀態(tài)模式的主要缺點(diǎn)如下:
(1) 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)中類和對(duì)象的個(gè)數(shù),導(dǎo)致系統(tǒng)運(yùn)行開銷增大。
(2) 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂,增加系統(tǒng)設(shè)計(jì)的難度。
(3) 狀態(tài)模式對(duì)“開閉原則”的支持并不太好,增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無法轉(zhuǎn)換到新增狀態(tài);而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼。
在以下情況下可以考慮使用狀態(tài)模式:
(1) 對(duì)象的行為依賴于它的狀態(tài)(如某些屬性值),狀態(tài)的改變將導(dǎo)致行為的變化。
(2) 在代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語句,這些條件語句的出現(xiàn),會(huì)導(dǎo)致代碼的可維護(hù)性和靈活性變差,不能方便地增加和刪除狀態(tài),并且導(dǎo)致客戶類與類庫之間的耦合增強(qiáng)。
Sunny 軟件公司欲開發(fā)一款紙牌游戲軟件,在該游戲軟件中用戶角色具有入門級(jí)(Primary)、熟練級(jí)(Secondary)、高手級(jí)(Professional)和骨灰級(jí)(Final)四種等級(jí),角色的等級(jí)與其積分相對(duì)應(yīng),游戲勝利將增加積分,失敗則扣除積分。入門級(jí)具有最基本的游戲功能 play() ,熟練級(jí)增加了游戲勝利積分加倍功能 doubleScore(),高手級(jí)在熟練級(jí)基礎(chǔ)上再增加換牌功能changeCards(),骨灰級(jí)在高手級(jí)基礎(chǔ)上再增加偷看他人的牌功能 peekCards()。
試使用狀態(tài)模式來設(shè)計(jì)該系統(tǒng)。
(1) 分析如下代碼:
class TestXYZ {
int behaviour;
//Getter and Setter
......
public void handleAll() {
if (behaviour == 0) { //do something }
else if (behaviour == 1) { //do something }
else if (behaviour == 2) { //do something }
else if (behaviour == 3) { //do something }
... some more else if ...
}
}
為了提高代碼的擴(kuò)展性和健壯性,可以使用( )設(shè)計(jì)模式來進(jìn)行重構(gòu)。
A. Visitor(訪問者)
B. Facade(外觀)
C. Memento(備忘錄)
D. State(狀態(tài))
(2) 傳輸門是傳輸系統(tǒng)中的重要裝置。傳輸門具有 Open(打開)、Closed(關(guān)閉)、Opening(正在打開)、StayOpen(保持打開)、Closing(正在關(guān)閉)五種狀態(tài)。觸發(fā)狀態(tài)的轉(zhuǎn)換事件有 click、complete 和 timeout 三種。事件與其相應(yīng)的狀態(tài)轉(zhuǎn)換如圖所示。
http://wiki.jikexueyuan.com/project/design-pattern-behavior/images/1358695550_1995.jpg" alt="傳輸門響應(yīng)事件與其狀態(tài)轉(zhuǎn)換圖" />
試使用狀態(tài)模式對(duì)傳輸門進(jìn)行狀態(tài)模擬,要求繪制相應(yīng)的類圖并編程模擬實(shí)現(xiàn)。