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