一個對象有多種狀態(tài),在不同的狀態(tài)下,同一種方法有不同的行為。如果用swich-case語句,將有大量的條件分支和邏輯代碼混在一起。狀態(tài)模式將每個狀態(tài)封裝到一個獨立的類中,利用多態(tài)性使得不同狀態(tài)下同一種方法表現(xiàn)不同的行為。
狀態(tài)模式的UML圖如下:

星際中人族的機槍兵Marine有兩種狀態(tài):普通狀態(tài)和打了興奮針后的狀態(tài),兩種狀態(tài)下機槍兵的開槍頻率是不同的,我們用狀態(tài)模式來實現(xiàn)機槍兵的fire()方法。
首先定義抽象狀態(tài)State接口,這個接口指定了機槍兵的fire行為:
public interface State {
public void fire();
}State接口有一個fire()方法,我們實現(xiàn)兩個子類NormalState和ExcitedState,分別表示普通狀態(tài)和打了興奮針后的狀態(tài),并實現(xiàn)具體的fire方法:
public class NormalState implements State {
public void fire() {
System.out.println("普通狀態(tài)每秒開槍1次。");
}
}
public class ExcitedState implements State {
public void fire() {
System.out.println("興奮狀態(tài)每秒開槍2次。");
}
}最后,定義機槍兵類Marine,每個Marine的實例代表一個機槍兵:
public class Marine {
// 保持一個狀態(tài)類的實例:
private State state = new NormalState();
// 為機槍兵設(shè)置狀態(tài):
public void setState(State state) {
this.state = state;
}
// fire()方法,實際調(diào)用的是state變量的fire()方法:
public void fire() {
state.fire();
}
}最后我們看看如何在客戶端控制一個機槍兵的狀態(tài):
public static void main(String[] args) {
// 創(chuàng)建一個機槍兵的實例:
Marine marine = new Marine();
// 調(diào)用fire()方法:
marine.fire();
// 設(shè)置為興奮狀態(tài):
marine.setState(new ExcitedState());
// 再調(diào)用fire()方法:
marine.fire();
}對同一個Marine對象調(diào)用兩次fire()方法,屏幕輸出為:
普通狀態(tài)每秒開槍1次。
興奮狀態(tài)每秒開槍2次。可見機槍兵在兩種狀態(tài)下的同一個fire()方法有不同的行為。
使用狀態(tài)模式的好處是每個狀態(tài)被封裝到一個獨立的類中,這些類可以獨立變化,而主對象中沒有繁瑣的swich-case語句,并且添加新的狀態(tài)非常容易,只需要從State派生一個新類即可。
(參考:Design Patterns)