介绍
有限状态机通常用于模拟序列逻辑,换句话说,就是用于代表和控制执行流程。
有限状态机所需条件:
- 一个物体只有固定的几种状态(例如交通灯只有绿灯、黄灯和红灯三个状态)。
- 有固定的变化顺序(例如交通灯只能绿灯->黄灯->红灯->绿灯循环)
- 物体同一时间点上只有一种状态。
例子
这里拿一个空调做例子,图是用了别人的,这里说明下下面三个状态的意思:
Off:空调关机
FanOnly:空调仅吹风
Cool:空调制冷
原始的解决办法
StateEnum
用枚举类定义三种状态
package org.example.origin; |
|
public enum StateEnum { |
|
POWER_OFF, FAN_ONLY, COOL |
|
} |
OriginAction
pressPowerOff()
表示点开关按钮,pressCool()
表示点击制冷按钮。
package org.example.origin; |
|
public class OriginAction { |
|
private StateEnum stateEnum; |
|
public OriginAction() { |
|
this.stateEnum = StateEnum.POWER_OFF; |
|
} |
|
public void pressPowerOff() { |
|
// 关机->吹风 |
|
if (stateEnum == StateEnum.POWER_OFF) { |
|
this.stateEnum = StateEnum.FAN_ONLY; |
|
System.out.println("Power on succeed."); |
|
} else { |
|
// 吹风或制冷->关机 |
|
this.stateEnum = StateEnum.POWER_OFF; |
|
System.out.println("Power off succeed."); |
|
} |
|
} |
|
public void pressCool() { |
|
if (stateEnum == StateEnum.POWER_OFF) { |
|
System.out.println("Cool failed because power off."); |
|
} else if (stateEnum == StateEnum.FAN_ONLY) { |
|
// 吹风->制冷 |
|
this.stateEnum = StateEnum.COOL; |
|
System.out.println("Open cool succeed."); |
|
} else { |
|
// 制冷->吹风 |
|
this.stateEnum = StateEnum.FAN_ONLY; |
|
System.out.println("Close cool succeed"); |
|
} |
|
} |
|
} |
OriginTest
编写测试类
package org.example.origin; |
|
public class OriginTest { |
|
public static void main(String[] args) { |
|
OriginAction originAction = new OriginAction(); |
|
originAction.pressCool(); |
|
originAction.pressPowerOff(); |
|
originAction.pressCool(); |
|
originAction.pressCool(); |
|
originAction.pressPowerOff(); |
|
} |
|
} |
执行结果:
Cool failed because power off.
Power on succeed.
Open cool succeed.
Close cool succeed
Power off succeed.
使用有限状态机解决
FiniteStateMachineEnum
这里使用了 Java 的枚举类,确保了类型约束。
package org.example.state; |
|
public enum FiniteStateMachineEnum { |
|
POWER_OFF { |
|
// 关机->吹风 |
|
@Override |
|
public FiniteStateMachineEnum pressPowerOff() { |
|
System.out.println("Power on succeed."); |
|
return FiniteStateMachineEnum.FAN_ONLY; |
|
} |
|
// 无效 |
|
@Override |
|
public FiniteStateMachineEnum pressCool() { |
|
System.out.println("Cool failed because power off."); |
|
return FiniteStateMachineEnum.POWER_OFF; |
|
} |
|
}, |
|
FAN_ONLY { |
|
// 吹风->关机 |
|
@Override |
|
public FiniteStateMachineEnum pressPowerOff() { |
|
System.out.println("Power off succeed."); |
|
return FiniteStateMachineEnum.POWER_OFF; |
|
} |
|
// 吹风->制冷 |
|
@Override |
|
public FiniteStateMachineEnum pressCool() { |
|
System.out.println("Open cool succeed."); |
|
return FiniteStateMachineEnum.COOL; |
|
} |
|
}, |
|
COOL { |
|
// 制冷->关机 |
|
@Override |
|
public FiniteStateMachineEnum pressPowerOff() { |
|
System.out.println("Power off succeed."); |
|
return FiniteStateMachineEnum.POWER_OFF; |
|
} |
|
// 制冷->吹风 |
|
@Override |
|
public FiniteStateMachineEnum pressCool() { |
|
System.out.println("Close cool succeed"); |
|
return FiniteStateMachineEnum.FAN_ONLY; |
|
} |
|
}; |
|
public abstract FiniteStateMachineEnum pressPowerOff(); |
|
public abstract FiniteStateMachineEnum pressCool(); |
|
} |
FiniteStateMachineTest
编写测试类
package org.example.state; |
|
public class FiniteStateMachineTest { |
|
public static void main(String[] args) { |
|
FiniteStateMachineEnum stateEnum = FiniteStateMachineEnum.POWER_OFF; |
|
stateEnum.pressCool() |
|
.pressPowerOff() |
|
.pressCool() |
|
.pressCool() |
|
.pressPowerOff(); |
|
} |
|
} |
执行结果:
Cool failed because power off.
Power on succeed.
Open cool succeed.
Close cool succeed
Power off succeed.