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 | 开门 行为 | 关门 行为 | 运行 行为 | 停止 行为 |
---|---|---|---|---|
开门 态 | no | yes | no | no |
关门 态 | yes | no | yes | yes |
运行 态 | no | no | no | yes |
停止 态 | yes | no | yes | no |
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(); }
运行结果
执行开门动作
执行关门动作
电梯上下运行中...
电梯停止运行...
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。