Java中的狀態模式實例教程
狀態模式是一種行為設計模式。適用於當對象的內在狀態改變它自身的行為時。
如果想基於對象的狀態來改變自身的行為,通常利用對象的狀態變量及if-else條件子句來扮演針對對象的不同行為。狀態模式Context(環境)和State(狀態)分離的方式既保證狀態與行為的聯動變化,又使得這種變化是條理明晰且鬆耦合的。
Context是包含了狀態引用的類,此引用指向一個狀態的具體實現。並且幫助把對狀態的請求委托給此狀態的對象進行處理。看一個具體的例子。
假如想實現電視遙控器,使用簡單按鍵來表現動作。如果狀態是ON,電視將被打開,如果狀態是OFF,電視將被關閉。
利用if-else條件子句來實現。
package com.journaldev.design.state; public class TVRemoteBasic { private String state=""; public void setState(String state){ this.state=state; } public void doAction(){ if(state.equalsIgnoreCase("ON")){ System.out.println("TV is turned ON"); }else if(state.equalsIgnoreCase("OFF")){ System.out.println("TV is turned OFF"); } } public static void main(String args[]){ TVRemoteBasic remote = new TVRemoteBasic(); remote.setState("ON"); remote.doAction(); remote.setState("OFF"); remote.doAction(); } }
注意:客戶端代碼需要知道每一個不同的值所代表的遙控器的不同狀態。如果這樣,假如大量的狀態被增加,那麼對於被緊緊捆綁在一起的狀態實現以及相應的客戶端代碼,它們的維護及擴展就變得非常困難。
現在使用狀態模式實現上述電視控製器。
抽象State接口
首先創建一個狀態接口來定義一個方法,此方法需要被不同的具體狀態類以及環境類實現。
package com.journaldev.design.state; public interface State { public void doAction(); }
具體State實現
自此例子中,包含兩個狀態:一個是打開電視的狀態,一個關閉電視的狀態。因此,需要創建兩個具體狀態類代表這兩個行為。
package com.journaldev.design.state; public class TVStartState implements State { @Override public void doAction() { System.out.println("TV is turned ON"); } }
package com.journaldev.design.state; public class TVStopState implements State { @Override public void doAction() { System.out.println("TV is turned OFF"); } }
現在我們開始實現Context對象,能改基於內在對象來改變自身的行為。
Context類實現
package com.journaldev.design.state; public class TVContext implements State { private State tvState; public void setState(State state) { this.tvState=state; } public State getState() { return this.tvState; } @Override public void doAction() { this.tvState.doAction(); } }
注意,Context類實現了狀態以及保持了對此狀態的引用。它能夠把對此狀態的請求委托到某一具體狀態實現中。
測試程序
完成一個簡單地程序對使用狀態模式的電視遙控器的測試。
package com.journaldev.design.state; public class TVRemote { public static void main(String[] args) { TVContext context = new TVContext(); State tvStartState = new TVStartState(); State tvStopState = new TVStopState(); context.setState(tvStartState); context.doAction(); context.setState(tvStopState); context.doAction(); } }
上述程序的輸出與沒用使用任何設計模式的電視控製器的實現類似。
使用狀態設計模式的優勢就是實現多態性的過程是清晰可見的。狀態的改變中產生的錯誤也較少,另外增加更多的狀態以及行為變得容易且更具魯棒性。此外狀態模式也幫助避免if-else子句或者switch-case條件判定邏輯。
狀態模式類似於策略模式,請看Java中的策略模式。這就是全部的狀態設計模式,希望你喜歡上它了。
最後更新:2017-05-23 11:31:53