模式定義
允許一個對象在其內部狀態發生改變時改變它的行為。對象看起來似乎修改了它的類。
狀態模式(State Pattern)主要解決的是在開發中時常遇到的根據不同的狀態需要進行不同的處理操作的問題,面對這樣的問題,大部分人是采用switch-case或者if-else語句 進行處理的,這樣會造成一個問題:分支過多,而且如果加入一個新的狀態就需要對原來的代碼進行編譯。
狀態模式采用了對這些不同的狀態進行封裝的方式 處理這類問題,當狀態改變的時候進行處理然后再切換到另一種狀態,也就是說把狀態的切換責任交給了具體的狀態類去負責。
模式結構
state.png
- Context:上下文環境,定義客戶感興趣的類。
- State:定義一個接口以封裝與Context的一個特定的狀態相關的行為。
- ConcreteState:具體的狀態子類,每一個子類實現一個與Context的一個狀態相關的行為。
代碼示例
標準模式
下面 我們通過Java代碼來詮釋一下原始的狀態模式。
首先是上下文環境Context :
public class Context {
private State state;//持有一個State類型的對象實例
public void setState(State state) {
this.state = state;
}
public void request(String param) {
//轉調state來處理
state.handle(param);
}
}
public interface State {
void handle(String param);
}
State 接口的具體實現類:
public class ConcreteStateA implements State {
@Override
public void handle(String param) {
System.out.println("ConcreteStateA handle param:" + param);
}
}
public class ConcreteStateB implements State {
@Override
public void handle(String param) {
System.out.println("ConcreteStateB handle param:" + param);
}
}
Client:
//創建狀態
State state = new ConcreteStateA();
//創建環境
Context context = new Context();
//將狀態設置到環境中
context.setState(state);
//請求
context.request("test");
優缺點
優點
- 結構清晰:避免了過多的switch……case或者if……else語句,避免了程序的復雜性,提高系統的可維護性。
- 遵循設計原則:很好的體現了開閉原則和單一職責原則,每個狀態都是一個子類,你要增加狀態就要增加子類,你要修改狀態,只要修改一個子類就可以了。
- 封裝性非常好:這也是狀態模式的基本要求,狀態變換放置到類的內部實現,外部的調用不知道內部如何實現和行為的變換。
狀態模式的缺點
- 子類會太多,也就是類膨脹,如果一個事物有很多狀態也不稀奇,如果完全使用狀態模式就會有太多的子類,不好管理,這個需要使用者衡量。