状态机适用场景:
C的操作,需要等到A、B的两个操作(A、B顺序操作),那就需要在 A、B之间创建一个状态机(state machine),C的操作需要状态机达到某一个状态才能进行
1. Overview
java版的状态机的原理其实就是java中的枚举类Enum,所以在进行状态机设计之前,先学习一下(回顾一个java Enum)
2. Java Enums
一个简单的例子:员工请假系统,员工到HR那离(submitted)-> 部门领导(Escalated) -> 部门经理(Approved)
public enumLeaveRequestState {
Submitted,
Escalated,
Approved
}
我们可以这样引用:
LeaveRequestState state = LeaveRequestState.Submitted;
java的枚举也可以包含方法,我们可以在枚举类中写一个抽象方法(abstract),这样枚举类中的每个成员都会继承该方法,这个就是java版状态机的核心所在
public enumLeaveRequestState {
Submitted {
@OverridepublicString responsiblePerson() {return "Employee";
}
},
Escalated {
@OverridepublicString responsiblePerson() {return "Team Leader";
}
},
Approved {
@OverridepublicString responsiblePerson() {return "Department Manager";
}
};public abstractString responsiblePerson();
}
注意上面的逗号,以及抽象方法前的分号
在下面的例子中, 我们使用上面代码中的 responsiblePerson() 方法. 这就是一个典型的状态机. 我们想知道"Escalated "的“状态”(实际是审批人), 那就会返回结果 “Team Leader”:
LeaveRequestState state =LeaveRequestState.Escalated;
assertEquals("Team Leader", state.responsiblePerson());
同样的 “Department Manager”:
LeaveRequestState state =LeaveRequestState.Approved;
assertEquals("Department Manager", state.responsiblePerson());
3. State Machines
状态机又称有限状态机,是一个建立在抽象机器上的计算模型,这个状态机在给定的时间内,只能有一个状态,而每一个状态又可以转换为其他状态(其他状态也是我们自己定义的)
4. Enums as State Machines
public enumLeaveRequestState {
Submitted {
@OverridepublicLeaveRequestState nextState() {returnEscalated;
}
@OverridepublicString responsiblePerson() {return "Employee";
}
},
Escalated {
@OverridepublicLeaveRequestState nextState() {returnApproved;
}
@OverridepublicString responsiblePerson() {return "Team Leader";
}
},
Approved {
@OverridepublicLeaveRequestState nextState() {return this;
}
@OverridepublicString responsiblePerson() {return "Department Manager";
}
};public abstractLeaveRequestState nextState();public abstractString responsiblePerson();
}
LeaveRequestState state =LeaveRequestState.Submitted;
state=state.nextState();
assertEquals(LeaveRequestState.Escalated, state);
state=state.nextState();
assertEquals(LeaveRequestState.Approved, state);
state=state.nextState();
assertEquals(LeaveRequestState.Approved, state);