赞
踩
初识
我第一次知道状态机,是在大学学习《数字电子技术基础》的时候。一块控制芯片有若干输入数据总线Data_in,一个CLK时钟震荡输入,还有一定数量的以高低电平组合来控制状态的输入。不同的状态,芯片会对输入的数据进行不同的处理。
再之后是读研时跟着导师做课题,用Verilog HDL写FPGA程序,仿真一些数字信号的处理算法,其中也大量使用了状态机编程。
还记得有一次和导师沟通科研时,他提及说状态机的这种编程模型,在软件行业也是有所应用的。当时我还是个编程战五渣,也不知道有设计模式这个东西,只是不以为意得应承地点点头。现在想想,还是蛮佩服导师的博学多知的。
再看状态机
状态机的官方定义如下:
The intent of the STATE pattern is to distribute state-specific logic across classes that represent an object’s state.
状态模式是为了将与状态有关的逻辑分写在代表对象状态的类中
我们来通过举例理解这句话。
想象你要实现一个登陆系统,用户将通过以下几个步骤与系统交互。
连接进登陆界面。
输入用户名密码,点击登陆
登陆成功则顺利进入系统,登陆失败则断开连接。
注销登录,断开连接。
登录流程图
这些步骤我们抽象成状态转移图来看会更加清晰
登录状态转移图
更一般的,我们稍微增加些健壮性的操作。
登录状态转移健壮性增强
这样简单的逻辑,我们可以不假思索得很快的在一份代码中完成。只要使用switch语法,对对象当前的状态做判断,然后在给各个分支中写上各自的逻辑。但是,如果你需要增加一个中间状态,或者修改某一个分支的逻辑时,你将不得不修改这个类的代码,增加case分支,修改逻辑。这违反了软件设计中的“开放封闭原则”。为此,我们将状态模式的概念付诸实施,将与指定状态有关的逻辑操作分别写在对应的可代表状态的类里。
状态机模式
UML视图
首先定义一个接口IState,指定所有的动作(Action)
/**
* the interface of state, input parameter is target state machine,
* and return the next state
* @author simple
* 2017年11月6日 上午10:29:58
*/
public interface IState {
public IState connect(Context context);
public IState beginToLogin(Context context);
public IState loginFailure(Context context);
public IState loginSuccess(Context context);
public IState logout(Context context);
}
定义一个抽象类,封装一些公共方法和实例成员
public abstract class AbstractState implements IState{
private StateEnum stateEnum;
public AbstractState(StateEnum stateEnum)
{
this.stateEnum = stateEnum;
}
public StateEnum getStateEnum() {
return stateEnum;
}
public void setStateEnum(StateEnum stateEnum) {
this.stateEnum = stateEnum;
}
public String toString()
{
return(stateEnum.toString());
}
}
StateEnum是一个枚举类,用来限定状态的类型。通过在构造器中传入一个枚举,来指明这个类代表什么状态。
public enum StateEnum {
UNCONNECTED(0, "UNCONNECTED"),
CONNECTED(1, "CONNECTED"),
LOGINING(2, "LOGINING"),
LOGIN_INTO_SYSTEM(3, "LOGIN_INTO_SYSTEM");
private int key;
private String stateStr;
StateEnum(int key, String stateStr)
{
this.key = key;
this.stateStr = stateStr;
}
void printState()
{
System.out.println(String.format("current state: %d: %s", this.key, this.stateStr));
}
}
通过继承AbstractState来定义IState的多个实现类,表示不同的状态。所有状态都需
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。