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

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