狀態模式

壹頁書發表於2014-03-22

模擬電梯

定義電梯介面

public interface ILift{
    // 開門
    public void open();
    // 關門
    public void close();
    // 能執行
    public void run();
    // 停
    public void stop();
}

實現

public class Lifi implements ILift{
    // 關閉
    public void close(){
        // 關門
    }
    // 開門
    public void open(){
        // 開門
    }
    // 執行
    public void run(){
        // 執行
    }
    // 停止
    public void stop(){
        // 停止
    }
}

書寫場景類

public class Client{
    public static void main(String[] args){
        ILift lift = new Lift();
        // 開門
        lift.open();
        // 關門
        lift.close();
        // 執行
        lift.run();
        // 停止
        lift.stop();
    }
}

更改

目前不清楚電梯的狀態,所以增加電梯的狀態

public interface ILift{
    // 四個狀態
    // 開門
    public final static int OPENING_STATE = 1;
    // 關門
    public final static int CLOSEING_STATE = 2;
    // 執行
    public final static int RUNNING_STATE = 3;
    // 停止
    public final static int STOPPING_STATE = 4;
    // 設定狀態
    public void setState(int state);
    // 下方相同
}
// 實現類
public class Lift implements ILift{
    private int state;
    public void setState(int state){
        this.state = state;
    }
    // 當電梯門關閉
    public void close(){
        // 關閉
        switch(this.state){
            case OPENING_STATE; // 關門
            this.closeWithoutLogic();
            // 修改狀態
        }
    }
    // 下方同理
}

修改

對電梯的狀態進行封裝,當呼叫的時候,直接自動改變電梯的狀態。
即,迪米特法則
即,外界不需要知道電梯的狀態,為一個封裝好的。

public abstract class LiftState{
    // 定義環境角色
    protected Context context;
    // 設定狀態
    public void setContext(Context _context){
        this.context = _context;
    }
    // 開門
    public abstract void open();
    // 關門
    public abstract void close();
    // 執行
    public abstract void run();
    // 停
    public abstract void stop();
}

開門狀態

public class OpenningState extends LiftState{
    // 關門
    @Override
    public void close(){
        // 狀態更改
        super.context.setLiftState(Context.closeingState);
        // 委託執行
        super.context.getLiftState().close();
    }
    // 開啟電梯門
    @Override
    public void open(){
        // 開門
    }
    // 執行
    @Override
    public void run(){
        // 門開,禁止執行
    }
    // 關門
    @Override
    public void stop(){
        // 開門的狀態即停止
    }
}
// 環境類,用於封裝當前電梯的狀態
public class Context{
    // 定義電梯狀態
    public final static OpenningState openningState = new OpenningState();
    // 剩下三個狀態相同
    // 當前狀態
    private LiftState liftState;
    // 獲得狀態
    public LiftState getLiState(){
        return liftState;
    }
    // 設定狀態
    public LiftState setLiftState(LiftState liftState){
        this.liftState = liftState;
        // 通知到當前的狀態
        this.liftState.setContext(this);
    }
}

剩下的幾個相同

// 書寫場景類
public class Client{
    public static void main(String[] args){
        // 此時定義一個電梯的狀態
        Context context = new Context();
        // 此時電梯進入關閉狀態
        // 將關閉狀態,儲存進入context中
        // 進行通知,將當前狀態的父類設定為context
        context.setLiFtState(new ClosingState());
        // 代執行ClosingState
        context.open();
        // 發生關閉狀態的時候,
        context.close();
        context.run();
        context.stop();
    }
}

總結

狀態模式的核心在於封裝,將物件的狀態進行封裝。
在於通知,當狀態發生改變的時候,進行通知。

圖片描述

相關文章