淺析設計模式之八 狀態模式
阿新 • • 發佈:2017-07-17
rri 關於 eas print 當前 自己 實現 cnblogs lds
傳統的狀態大都是這樣的(狀態模式)
public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; final static int HAS_QUARTER = 2; final static int SOLD = 3; }然後嵌入大量的if - else 根究當前狀態來進行某些操作,但是呢,現在我們是學過設計模式的人了,我們總是想搞出點幺蛾子來封裝一下我們想要的東西,換句話說,我們要遵守"封裝變化"原則 創建一個接口,填充我們需要的某些行為
/*** 狀態接口 * @author Dougest 2017年7月16日 下午11:19:57 * */ public interface State { void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }
然後通過幾個實現類來實現我們不同狀態寫的具體細節
/** * 狀態實現類 * @author Dougest 2017年7月16日 下午11:19:57 * */ public class SoldState { voidinsertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }
/** * 狀態實現類 * @author Dougest 2017年7月16日 下午11:19:57 * */ public class SoldOutState { void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }
/** * 狀態實現類 * @author Dougest 2017年7月16日 下午11:19:57 **/ public class NoQuarterState { void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }
/** * 狀態實現類 * @author Dougest 2017年7月16日 下午11:19:57 * */ public class HasQuarterState { void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }現在來具體實現 接口不變,實現新的調用類
/** * * @author Dougest 2017年7月17日 上午12:10:47 * */ public class CompleMachine { State noQuarterState; State hasQuarterState; State soldOutState; State soldState; State state = soldOutState; int count = 0; public CompleMachine(int numberCompleMachine) { noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldOutState = new SoldOutState(this); soldState = new SoldState(this); this.count = numberCompleMachine; if(numberCompleMachine > 0) state = noQuarterState; } public void insertQuarter() { state.insertQuarter(); } public void ejectQuarter() { state.ejectQuarter(); } public void turnCrank() { state.turnCrank(); state.dispense(); } void setState(State state) { this.state = state; } void releaseBall() { if(count != 0) count = count -1; } public int getCount() { return this.count; } public State getNoQuarterState() { return noQuarterState; } public void setNoQuarterState(State noQuarterState) { this.noQuarterState = noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public void setHasQuarterState(State hasQuarterState) { this.hasQuarterState = hasQuarterState; } public State getSoldOutState() { return soldOutState; } public void setSoldOutState(State soldOutState) { this.soldOutState = soldOutState; } public State getSoldState() { return soldState; } public void setSoldState(State soldState) { this.soldState = soldState; } public State getState() { return state; } public void setCount(int count) { this.count = count; }
簡單的實現某一個狀態對象
/** * 狀態實現類 * @author Dougest 2017年7月17日 上午12:11:16 * */ public class HasQuarterState implements State { private CompleMachine compleMachine; public HasQuarterState(CompleMachine compleMachine) { this.compleMachine = compleMachine; } @Override public void insertQuarter() { System.out.println(""); } @Override public void ejectQuarter() { System.out.println(""); } @Override public void turnCrank() { System.out.println(""); } @Override public void dispense() { compleMachine.releaseBall(); if(compleMachine.getCount() > 0) compleMachine.setState(compleMachine.getHasQuarterState()); else compleMachine.setState(compleMachine.getSoldOutState()); }現在我們已經做到了如下幾點 1.將每個狀態的行為局部化到他自己的類中 2.將容易的產生問題的if語句刪除,方便日後維護 3.讓每一個狀態對修改關閉,對擴展開放,因為可以加入新的狀態 4.創建了一個新的代碼基和類,更能映射我們關於狀態的業務邏輯,更容易閱讀和理解 上面的代碼我們實現了定義狀態模式 定義狀態模式:允許對象在內部狀態改變時改變他的行為,對象看起來好像修了他的類 這個就有點我們前面講的命令模式的味道了,定義狀態模式將狀態封裝成對象,並將動作委托給代表當前狀態的對象,我們知道行為會隨著內部狀態而改變 這裏有一個習慣,如果沒有共同的功能可以放在抽象類中,我們通常使用接口,就比如這個demo
要點: 狀態模式允許一個對象基於內部的狀態而擁有不同的行為 和程序狀態機(PSM)不同,狀態模式用類代表狀態 context會將行為委托給當前狀態對象 通過將每一個狀態封裝成對象,我們把以後需要做的任何改變局部化了 狀態模式和策略模式有相同的類圖,但是他們的意圖不一樣 策略模式通常會用行為或者算法來配置context類 狀態模式允許context類隨著狀態的改變而改變行為 狀態轉換可以有State類或者context類控制 使用狀態模式通常會使設計中出現大量的類 狀態類可以被多個context共享
淺析設計模式之八 狀態模式