java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java有限状态机

Java中的有限状态机(设计模式——状态模式)

作者:bjxiaxueliang

这篇文章主要介绍了Java中的有限状态机(设计模式——状态模式),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java有限状态机 (设计模式——状态模式)

编写代码的时候,有时会遇见较为复杂的 swith...case... if...else... 语句。

这一刻有时会想到状态机,用 有限状态机 替换 swith...case... if...else... 可以:

以上是有限状态机的好处。

其亦有 缺点

状态模式定义

Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.

允许对象在其内部状态发生变化时更改其行为。

看起来像更改了其类 (这翻译不好,这里 应该是体现了其封装性:外部的调用不用知道其内部如何实现状态和行为变化的)。

举个例子

我们每天都乘坐电梯,电梯有四种状态: 开门、关门、运行、停止。

Col1开门 行为关门 行为运行 行为停止 行为
开门 态noyesnono
关门 态yesnoyesyes
运行 态nononoyes
停止 态yesnoyesno

LiftState.java

/**
 * 定义电梯行为:打开、关闭、运行、停止
 */
public abstract class LiftState {
    // 拥有一个电梯对象,用于更新电梯当前状态
    protected Lift mLift;
    /**
     * 通过构造函数引入电梯的实例化对象
     *
     * @param lift
     */
    public LiftState(Lift lift) {
        this.mLift = lift;
    }
    /**
     * 行为:打开电梯门
     */
    public abstract void open();
    /**
     * 行为:关闭电梯门
     */
    public abstract void close();
    /**
     * 行为:电梯运行
     */
    public abstract void run();
    /**
     * 行为:电梯停止运行
     */
    public abstract void stop();
}

电梯的四种状态

public class OpeningState extends LiftState {
    public OpeningState(Lift lift) {
        super(lift);
    }
    @Override
    public void open() {
        // 执行开门动作
        System.out.println("执行开门动作");
    }
    @Override
    public void close() {
        // 执行关门动作
        // 1、转化为关门状态
        mLift.setState(mLift.getCloseingState());
        // 2、关门
        mLift.close();
    }
    @Override
    public void run() {
        // do noting
        // 开门状态,不能执行运行动作
    }
    @Override
    public void stop() {
        // do noting
        // 开门状态下,不执行停止动作
    }
}
public class ClosingState extends LiftState {
    public ClosingState(Lift lift) {
        super(lift);
    }
    @Override
    public void open() {
        // 执行开门动作
        // 1、变化为开门状态
        this.mLift.setState(mLift.getOpenningState());
        // 2、开门
        this.mLift.open();
    }
    @Override
    public void close() {
        System.out.println("执行关门动作");
    }
    @Override
    public void run() {
        // 运行动作
        // 1、运行状态
        this.mLift.setState(mLift.getRunningState());
        // 2、运行动作
        this.mLift.run();
    }
    @Override
    public void stop() {
        // 停止动作
        // 1、转化为停止状态
        this.mLift.setState(mLift.getStoppingState());
        // 2、停止
        this.mLift.stop();
    }
}
public class RunningState extends LiftState {
    public RunningState(Lift lift) {
        super(lift);
    }
    @Override
    public void open() {
        // do noting
    }
    @Override
    public void close() {
        // do noting
    }
    @Override
    public void run() {
        // 运行动作
        System.out.println("电梯上下运行中...");
    }
    @Override
    public void stop() {
        // 停止动作
        // 1、转化为停止状态
        this.mLift.setState(mLift.getStoppingState());
        // 2、停止动作
        this.mLift.stop();
    }
}
public class StoppingState extends LiftState {
    public StoppingState(Lift lift) {
        super(lift);
    }
    @Override
    public void open() {
        // 开门动作
        // 1、开门状态
        this.mLift.setState(mLift.getOpenningState());
        // 2、执行开门动作
        this.mLift.open();
    }
    @Override
    public void close() {
        // do noting
    }
    @Override
    public void run() {
        // 运行动作
        // 1、运行状态
        this.mLift.setState(mLift.getRunningState());
        // 2、运行动作
        this.mLift.run();
    }
    @Override
    public void stop() {
        // 电梯停止动作
        System.out.println("电梯停止运行...");
    }
}

定义电梯类

/**
 * 定义电梯类
 */
public class Lift {
    //定义出电梯的所有状态
    private LiftState openningState;
    private LiftState closingState;
    private LiftState runningState;
    private LiftState stoppingState;
    // 定义当前电梯状态
    private LiftState mCurState;
    /**
     * 构造方法
     */
    public Lift() {
        openningState = new OpeningState(this);
        closingState = new ClosingState(this);
        runningState = new RunningState(this);
        stoppingState = new StoppingState(this);
    }
    /**
     * 执行开门动作
     */
    public void open() {
        mCurState.open();
    }
    /**
     * 执行关门动作
     */
    public void close() {
        mCurState.close();
    }
    /**
     * 执行运行动作
     */
    public void run() {
        mCurState.run();
    }
    /**
     * 执行停止动作
     */
    public void stop() {
        mCurState.stop();
    }
    // ##################设置当前电梯状态#####################
    /**
     * 设置当前电梯状态
     *
     * @param state
     */
    public void setState(LiftState state) {
        this.mCurState = state;
    }
    // ###################获取电梯的全部状态####################
    public LiftState getOpenningState() {
        return openningState;
    }
    public LiftState getCloseingState() {
        return closingState;
    }
    public LiftState getRunningState() {
        return runningState;
    }
    public LiftState getStoppingState() {
        return stoppingState;
    }
}

运行

public static void main(String[] args) {
        Lift lift = new Lift();
        lift.setState(new ClosingState(lift));
        lift.open();
        lift.close();
        lift.run();
        lift.stop();
    }

运行结果

执行开门动作
执行关门动作
电梯上下运行中...
电梯停止运行...

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文