状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。(状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。)
State:状态。一个状态机至少要包含两个状态
Event:事件。事件就是执行某个操作的触发条件或者口令
Action:动作。事件发生以后要执行动作
Transition:变换。也就是从一个状态变化为另一个状态。指的是两个状态之间的一种关系,表明对象在第一个状态中执行一定的动作,并将在某个事件发生同时某个特定条件满足时进行第二个状态。
以音乐播放器为示例,状态转换图如下:
类图如下:
源码如下:
PlayerState表示状态抽象类
public abstract class PlayerState {
protected IPlayer mPlayer;
public PlayerState(IPlayer player) {
this.mPlayer=player;
}
public abstract void handle(int action) throws Exception;
}
PausedState
public class PausedState extends PlayerState {
public PausedState(IPlayer player) {
super(player);
}
@Override
public void handle(int action) throws Exception {
if(!Objects.equals(action, StateEnum.STOPPED.getValue())
&& !Objects.equals(action, StateEnum.PLAYING.getValue())) {
System.out.println("state is error, it should be stopped/playing status");
throw new Exception("error");
}
// 播放
if(Objects.equals(action, StateEnum.PLAYING.getValue())) {
System.out.println("开始播放......");
mPlayer.playVedio();
mPlayer.setState(new PlayingState(mPlayer));
}
// 停止
if(Objects.equals(action, StateEnum.STOPPED.getValue())) {
System.out.println("开始停止......");
mPlayer.stop();
mPlayer.setState(new StoppedState(mPlayer));
}
}
}
PlayingState
public class PlayingState extends PlayerState {
public PlayingState(IPlayer player) {
super(player);
}
@Override
public void handle(int action) throws Exception {
if(!Objects.equals(action, StateEnum.PAUSED.getValue())
&& !Objects.equals(action, StateEnum.STOPPED.getValue())) {
System.out.println("state is error, it should be paused/stopped status");
throw new Exception("error");
}
// 暂停
if(Objects.equals(action, StateEnum.PAUSED.getValue())) {
System.out.println("开始暂停......");
mPlayer.pause();
mPlayer.setState(new PausedState(mPlayer));
}
// 停止
if(Objects.equals(action, StateEnum.STOPPED.getValue())) {
System.out.println("开始停止......");
mPlayer.stop();
mPlayer.setState(new StoppedState(mPlayer));
}
}
}
StoppedState
public class StoppedState extends PlayerState {
public StoppedState(IPlayer player) {
super(player);
}
@Override
public void handle(int action) throws Exception {
if(!Objects.equals(action, StateEnum.PLAYING.getValue())) {
System.out.println("state is error, it should be playing status");
throw new Exception("error");
}
System.out.println("开始播放音乐......");
mPlayer.playVedio();
mPlayer.setState(new PlayingState(mPlayer));
}
}
音乐器
public abstract class IPlayer {
public abstract void request(int flag);
public abstract void setState(PlayerState state);
public abstract void playVedio();
public abstract void pause();
public abstract void stop();
}
public class VedioPlayer extends IPlayer {
private PlayerState initState = new StoppedState(this);
@Override
public void request(int flag) {
try {
initState.handle(flag);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void setState(PlayerState state) {
this.initState = state;
}
@Override
public void playVedio() {
System.out.println("play vedio!");
}
@Override
public void pause() {
System.out.println("pause vedio!");
}
@Override
public void stop() {
System.out.println("stop vedio!");
}
}
测试函数
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
IPlayer player=new VedioPlayer();
int i=-1;
while((i=sc.nextInt())!=-1){
player.request(i);
}
}
}
--------------以下输出
1
state is error, it should be playing status
java.lang.Exception: error
at state.StoppedState.handle(StoppedState.java:20)
at state.VedioPlayer.request(VedioPlayer.java:14)
at state.Main.main(Main.java:16)
2
开始播放音乐......
play vedio!
3
开始暂停......
pause vedio!
1
开始停止......
stop vedio!
2
开始播放音乐......
play vedio!