State(狀态)–對象行為型模式
一、意圖
允許一個對象在其内部狀态改變時改變它的行為。對象看起來似乎修改了它的類。
二、動機
1.在軟體建構過程中,某些對象的狀态如果改變,其行為也會随之而發生變化,比如文檔處于隻讀狀态,其支援的行為和讀寫狀态支援的行為就可能完全不同。
2.如何在運作時根據對象的狀态來透明地更改對象的行為?而不會為對象操作和狀态轉化之間引入緊耦合?
三、适用性
1.一個對象的行為取決于它的狀态,并且它必須在運作時刻根據狀态改變它的行為。
2.一個操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀态。這個狀态通常用一個或多個枚舉常量表示。通常,有多個操作包含這一相同的條件結構。State模式将每一個條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況将對象的狀态作為一個對象,者一對象可以不依賴于其他對象而獨立的變化。
四、結構

五、效果
1.它将于特定狀态相關的行為局部化,并且将不同狀态的行為分割開來。 State模式将所有于一個特定的狀态相關的行為都放入一個對象中。因為所有于狀态相關的代碼都存在于某一個State子類中,是以通過定義新的子類可以很容易的增加新的狀态和轉換。
2.它使得狀态轉化顯式化。 當一個對象僅以内部資料值來定義目前狀态時,其狀态僅表現為對一些變量的指派,這不夠明确。為不同的狀态引入獨立的對象使得轉換變得更加明确。而且,State對象可保證Context不會發生内部狀态不一緻的情況,因為從Context的角度看,狀态轉換是原子的——隻需要重新綁定一個變量(即Context的State對象變量),而無需為對個變量指派。
3.State對象可被共享。 如果State對象沒有執行個體變量——即他們表示的狀态完全以他們的類型來編碼——那麼各Context對象可以共享一個State對象。當狀态以這種方式被共享時,他們必然沒有内部狀态,隻有行為的輕量級對象。
六、實作
1.誰定義狀态轉換。 State模式不指定哪個一參與者定義狀态轉換準則。如果該準則是固定的,那麼他們可在Context中完全實作。然而若讓State子類自身指定他們的後繼狀态以及何時進行轉換,通常更靈活更合适,這需要Context增加一個接口,讓State對象顯示地設定Context的目前狀态。
用這種方法分散轉換邏輯可言很容易地定義新的State子類來修改和擴充該邏輯。這樣做的一個缺點是,一個State子類至少擁有一個其他子類資訊,這就在個子類之間産生了實作依賴。
2.基于表的另一種方式。
3.建立和銷毀State對象。 一個常見的值得考慮的實作上的權衡是,究竟是(1)僅需要State對象是才建立他們并随後銷毀他們,還是(2)提前建立他們并且始終不銷毀他們。
4.使用動态繼承。
七、要點總結
1.State模式将所有于一個特定狀态相關的行為都放入一個State的子類對象中,在對象狀态切換時,切換相應的對象;但同時維持State的接口,這樣實作了具體操作于狀态轉換之間的解耦。
2.為不同的狀态引入不同的對象使得狀态轉換變得更加明确,而且可以保證不會出現狀态不一緻的情況,因為轉換時原子性的——即要麼徹底轉換過來,要麼不轉換。
3.如果State對象沒有執行個體變量,那麼各個上下文可以共享一個State對象,進而節省對象開銷。
八、相關模式
Flyweight模式解釋了何時以及怎樣共享狀态對象。
狀态對象通常是Singleton。
九、舉例說明
人醉酒時的狀态和平時的狀态。
本文為李建忠設計模式視訊的筆記以及《設計模式-可複用面向對象的軟體的基礎》和自己的部分見解