1. 程式人生 > >淺析設計模式之八 狀態模式

淺析設計模式之八 狀態模式

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 {
    void
insertQuarter(); 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共享

淺析設計模式之八 狀態模式