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();
}
运行结果
执行开门动作
执行关门动作
电梯上下运行中...
电梯停止运行...
参考:
《设计模式之禅》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。