【设计模式】状态模式(状态机)
先介绍下状态机,状态机一般由三部分组成:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件 触发 状态的转移及动作的执行。不过,动作不是必须的,可能只转移状态,不执行任何动作。
状态模式通过将事件触发的状态转移和动作执行,拆分到不同的状态类中,来避免分支判断逻辑。下面展示“超级马里奥”小游戏的游戏状态之间的状态转换,
public interface IMario { State getName(); void obtainMushRoom(MarioStateMachine stateMachine); void obtainCape(MarioStateMachine stateMachine); void obtainFireFlower(MarioStateMachine stateMachine); void meetMonster(MarioStateMachine stateMachine); } public class SmallMario implements IMario { private static final SmallMario instance = new SmallMario(); private SmallMario() {} public static SmallMario getInstance() { return instance; } @Override public State getName() { return State.SMALL; } @Override public void obtainMushRoom(MarioStateMachine stateMachine) { stateMachine.setCurrentState(SuperMario.getInstance()); stateMachine.setScore(stateMachine.getScore() + 100); } @Override public void obtainCape(MarioStateMachine stateMachine) { stateMachine.setCurrentState(CapeMario.getInstance()); stateMachine.setScore(stateMachine.getScore() + 200); } @Override public void obtainFireFlower(MarioStateMachine stateMachine) { stateMachine.setCurrentState(FireMario.getInstance()); stateMachine.setScore(stateMachine.getScore() + 300); } @Override public void meetMonster(MarioStateMachine stateMachine) { // do nothing... } } // SuperMario、CapeMario、FireMario类... public class MarioStateMachine { private int score; private IMario currentState; public MarioStateMachine() { this.score = 0; this.currentState = SmallMario.getInstance(); } // 具体方法实现 }
实际上,像游戏这种比较复杂的状态机,包含的状态比较多,优先推荐使用查表法(映射表,状态映射事件,可构造多维数组),而状态模式会引入非常多的状态类,反而会导致代码比较难维护。相反,像电商、外卖下但这种类型的状态机,它们的状态并不多,状态转移也比较简单,但事件触发执行的动作包含的业务逻辑可能会比较复杂,所以,更适合使用状态模式来实现。
下一篇:
喊7的次数重排--Java实现