狀態模式(State Pattern),又稱爲狀態對象模式(Pattern of Objects for Statues),狀態模式是對象的行爲模式。
狀態模式把所研究的對象的行爲包裝在不一樣的狀態對象裏,每個狀態對象都屬於一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行爲也隨之改變。
模式所涉及角色有:
1.抽象狀態角色:定義接口,用以封裝環境(Context)對象的一個特定的狀態所對應的行爲
2.具體狀態角色:每個具體狀態類都實現了環境(Context)的一個狀態所對應 的行爲
3.環境(Context)角色:定義客戶端所感興趣的接口,而且保留一個具體狀態類的實例。這個具體狀態類的實例給出此環境對象的現有狀態。
示例代碼:
1 public class Test {
2
3 }
4 //環境角色,此例只給出一個具體狀態類或接口,實際狀況中會有不少具體狀態類,也就是環境類Context的行爲sampleOperation()是委派給一個具體狀態
5 //類的。經過多態性原則,能夠動態地改變環境類Context的屬性State的內容,使其從指向一個具體狀態類變換到指向另外一個具體狀態類,從而使環境類的行
6 //行爲sampleOperation()由不一樣的具體狀態類來執行。
7 class Context{
8 private State state;
9 public void sampleOperation(){
10 state.sampleOperation();
11 }
12 public void setState(State state){
13 this.state = state;
14 }
15 }
16
17 //抽象狀態角色
18 interface State{
19 public void sampleOperation();
20 }
21 //具體狀態角色
22 class ConcreteState implements State{
23
24 @Override
25 public void sampleOperation() {
26 System.out.println("Operation");
27 }
28
29 }
什麼狀況下使用狀態模式?
1.一個對象的行爲依賴於它所處的狀態,對象的行爲必須隨着其狀態的改變而改變
2.對象在某個方法裏依賴於一重或多重的條件轉移語句,其中有大量的代碼狀態模式把條件轉移語句的每個分支都包裝到一個單獨的類裏。這使得這些條件轉移分支可以以類的方式獨立存在和演化。維護這些獨立的類也就再也不影響到系統的其餘部分。
狀態模式常常與策略模式相混淆,有時候很難區分。這時,一個簡單的方法即是考察環境角色是否有明顯的狀態和狀態的過渡。環境角色只有一個狀態,那麼就應當使用策略模式。策略模式的特色是:一旦環境角色選擇了一個具體策略類,那麼在整個環境類的生命週期裏它都不會改變這個具體策略類。而狀態模式則適用於另外一種狀況,即環境角色有明顯的狀態轉移。在環境類的生命週期裏面,會有幾個不一樣的狀態對象被利用。另外一個區別在於,策略模式的環境類本身選擇一個具體策略類,而狀態模式的環境類是被外在緣由放進一個具體狀態中。策略模式所選的策略每每並不明顯地告訴客戶端它所選擇的具體策略:而狀態模式則相反,在狀態模式裏,環境角色所處的狀態是明顯告訴客戶端的。
對象在不一樣的狀態下的行爲包裝到不一樣的狀態類裏面,這是狀態模式所要求的。狀態模式所不指明的是控制狀態轉移的邏輯放在那裏。在實現時,這種邏輯能夠放在兩個地方:一是放在環境類裏面,二是包裝在狀態類裏面。狀態對象 本身決定什麼時候進行狀態轉移,以及下一個狀態是誰。