狀態(tài)模式
狀態(tài)模式:允許對象在內(nèi)部狀態(tài)改變時改變它的行為,對象看起來好像修改了它的類。
狀態(tài)模式的組成部份:
1.環(huán)境,是一個類,該類含有抽象狀態(tài)聲明的變量,可引用具體的狀態(tài)實例,用戶對環(huán)境類的實例在某一些狀態(tài)的行為感興趣.
2.抽象狀態(tài),抽象狀態(tài)是一個接口名抽象類,抽象狀態(tài)中定義了與環(huán)境的一個特定狀態(tài)相關的若干方法.
3.具體狀態(tài),實現(xiàn)抽象接口
各組成部份之間的關系:
例子
1.狀態(tài):

























2.具體狀態(tài)1:










3.具體狀態(tài)2










4.具體狀態(tài)3










5.環(huán)境

















6.測試























要點:
1. 策略模式和狀態(tài)模式是雙胞胎,它們有相同的類圖,但是它們的意圖不同。策略模式是圍繞可以互換的算法來成功創(chuàng)建業(yè)務的,然而狀態(tài)模式是通過改變對象內(nèi)部的狀態(tài)來幫助對象控制自己的行為.
2. Context將與狀態(tài)相關的操作委托給當前的Concrete State對象處理。
3. Context可將自身作為一個參數(shù)傳遞給處理該請求的狀態(tài)對象。這使得狀態(tài)對象在必要時可訪問Context。
4. Context或Concrete State類都可決定哪個狀態(tài)是另外哪一個的后繼者,以及是在何種條件下進行狀態(tài)轉(zhuǎn)換。也就是說可以在State中保存對Concrete State的引用,在必要時設置具體的狀態(tài),做到狀態(tài)的轉(zhuǎn)換。
5. 一般來講,當狀態(tài)轉(zhuǎn)換是固定的時候,狀態(tài)轉(zhuǎn)換就適合放在Context中。然而,當轉(zhuǎn)換是更動態(tài)的時候,通常會放到具體的狀態(tài)類中進行。(具體狀態(tài)類持有Context的引用,實現(xiàn)狀態(tài)的轉(zhuǎn)換)
適用性:
1. 一個對象的行為取決于它的狀態(tài) , 并且它必須在運行時刻根據(jù)狀態(tài)改變它的行為。
2. 一個操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態(tài)。這個狀態(tài)通常用一個或多個枚舉常量表示。通常,有多個操作包含這一相同的條件結(jié)構(gòu)。 State模式將每一個條件分支放入一獨立的類中。這使得你可以根據(jù)對象自身的情況將對象的狀態(tài)作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
效果:
1. State模式將與特定狀態(tài)相關的行為局部化,并且將不同狀態(tài)的行為分割開來。
State模式將所有與一個特定的狀態(tài)相關的行為都放入一個對象中。因為所有與狀態(tài)相關的代碼都存在于某一個State子類中, 所以通過定義新的子類可以很容易的增加新的狀態(tài)和轉(zhuǎn)換。
另一個方法是使用數(shù)據(jù)值定義內(nèi)部狀態(tài)并且讓Context操作來顯式地檢查這些數(shù)據(jù)。但這樣將會使整個Context的實現(xiàn)中遍布看起來很相似的條件語句或case語句。增加一個新的狀態(tài)可能需要改變?nèi)舾蓚€操作,這就使得維護變得復雜了。
State模式避免了這個問題,但可能會引入另一個問題,因為該模式將不同狀態(tài)的行為分布在多個State子類中。這就增加了子類的數(shù)目,相對于單個類的實現(xiàn)來說不夠緊湊。但是如果有許多狀態(tài)時這樣的分布實際上更好一些 , 否則需要使用巨大的條件語句。正如很長的過程一樣,巨大的條件語句是不受歡迎的。它們形成一大整塊并且使得代碼不夠清晰,這又使得它們難以修改和擴展。 State模式提供了一個更好的方法來組織與特定狀態(tài)相關的代碼。決定狀態(tài)轉(zhuǎn)移的邏輯不在單塊的 if或switch語句中, 而是分布在State子類之間。將每一個狀態(tài)轉(zhuǎn)換和動作封裝到一個類中,就把著眼點從執(zhí)行狀態(tài)提高到整個對象的狀態(tài)。這將使代碼結(jié)構(gòu)化并使其意圖更加清晰。
2. State對象可被共享。如果State對象沒有實例變量,即它們表示的狀態(tài)完全以它們的類型來編碼,那么各Context對象可以共享一個 State對象。