狀態模式(State Pattern)又稱為狀態對象模式,該模式允許一個對象在其內部狀態改變時改變其行為。 定義: 當一個對象內部狀態改變時允許改變行為,這個對象看起來像改變了其類型。 狀態模式的核心是封裝,狀態的變更引起行為的變動,從外部看來就好像該對象對應的類發生改變一樣。 狀態模式的類圖如下所 ...
狀態模式(State Pattern)又稱為狀態對象模式,該模式允許一個對象在其內部狀態改變時改變其行為。
定義:
- 當一個對象內部狀態改變時允許改變行為,這個對象看起來像改變了其類型。
- 狀態模式的核心是封裝,狀態的變更引起行為的變動,從外部看來就好像該對象對應的類發生改變一樣。
狀態模式的類圖如下所示。
狀態械涉及以下3個角色:
- 抽象狀態(State)角色:封裝環境對象的一個特定狀態所對應的行為。
- 具體狀態角色:實現環境狀態所對應的行為。
- 環境角色:該角色定義客戶端需要的介面,並負責具體狀態的切換。它會保留一個具體狀態類的實例,該實例給出環境對象的現有狀態。
State.java
// 抽象角色 public abstract class State { // 定義一個環境角色 protected Context context; // 設置環境 public void setContext(Context context) { this.context = context; } // 抽象行為 public abstract void handle(); }
Context.java
// 環境角色 public class Context { // 定義狀態 public static State STATE1 = new ConcreteState1(); public static State STATE2 = new ConcreteState2(); // 當前狀態 private State currentState; // 獲取當前狀態 public State getCurrentState() { return currentState; } // 設置當前狀態 public void setCurrentState(State currentState) { this.currentState = currentState; // 設置環境中的狀態 currentState.setContext(this); } // 行為委托 public void handle1() { // 切換到狀態1 this.setCurrentState(STATE1); this.currentState.handle(); } public void handle2() { // 切換到狀態1 this.setCurrentState(STATE2); this.currentState.handle(); } }
ConcreteState1.java
// 具體狀態1 public class ConcreteState1 extends State { // 狀態1的行為邏輯處理 @Override public void handle() { System.out.println("行為1的邏輯處理"); } }
ConcreteState2.java
// 具體狀態2 public class ConcreteState2 extends State { // 狀態2的行為邏輯處理 @Override public void handle() { System.out.println("行為2的邏輯處理"); } }
Client.java
// 應用程式 public class Client { public static void main(String[] args) { // 定義環境角色 Context context = new Context(); // 執行行為 context.handle1(); context.handle2(); } }
優點:
- 結構清晰。
- 遵循設計原則。
- 封裝性非常好。
缺點:
- 子類太多,不易管理。
應用場景:
- 對象的行為依賴於它所處的狀態,即行為隨狀態改變而改變的場景。
- 對象在某個方法里依賴於一重或多重條件分支語句,此時可以使用狀態模式將分支中的每一個分支都包裝到一個單獨的類中,使得這些條件分支能夠以類的方式單獨存在和演化。如此,維護這些獨立的類就不再影響到系統的其他部分。
摘自:
青島東合信息技術有限公司 . 設計模式(Java版) . 電子工業出版社,2012,170-172.