概述
备忘录模式:(Memento Design Pattern)在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。
何时使用:
- 状态模式一般用来实现状态机,而状态机常用在游戏、工作流引擎等系统开发中。
- 代码中包含大量与对象状态有关的条件语句。
什么是状态机?
- 状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。
UML 类图:
角色组成:
- 上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。
- 抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。
- 具体状态(Concrete State):实现抽象状态定义的接口。
通用代码
Context.java
1 | java复制代码public class Context { |
State.java
1 | java复制代码public abstract class State { |
ConcreteStateA.java、ConcreteStateB.java
1 | java复制代码public class ConcreteStateA extends State { |
测试:
1 | java复制代码public class Test { |
结果:
ConcreteStateA 状态的 handle 方法
当前状态为:通用模板.ConcreteStateA@1b6d3586
ConcreteStateB 状态的 handle 方法
当前状态为:通用模板.ConcreteStateB@4554617c
具体实例
相信很多人都玩过王者荣耀这款手游,在对局中,王者荣耀里面的英雄遭受到不同的技能或者增益buff会有不同的状态,比如眩晕、加速、减速等等。如果不使用状态模式的话,我们的英雄类会非常的复杂和难以维护。此时使用状态模式才是更好的选择,下面用代码模拟实现一遍。
RunState.java
1 | java复制代码public interface RunState { |
CommonState.java、SpeedUpState.java、SpeedDownState.java、SwimState.java
1 | java复制代码public class CommonState implements RunState { |
Hero.java
1 | java复制代码public class Hero { |
测试:
1 | java复制代码public class Test { |
结果:
————–开始跑动—————
————–加速跑动—————
——加速状态结束,变为正常状态——
————–减速跑动—————
——减速状态结束,变为正常状态——
————–不能跑动—————
——眩晕状态结束,变为正常状态——
————–停止跑动—————
总结
状态模式与策略模式区别
状态模式和策略模式的 UML 一样,但是解决的问题和侧重不一样。
- 状态模式重点在各状态之间的切换从而做不同的事情,而策略模式更侧重于根据具体情况选择策略,并不涉及切换。
- 状态模式不同状态下做的事情不同,而策略模式做的都是同一件事,例如聚合支付平台,有支付宝、微信支付、银联支付,虽然策略不同,但最终做的事情都是支付,也就是说他们之间是可替换的。反观状态模式,各个状态的同一方法做的是不同的事,不能互相替换。
- 状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而通过从Context中分离出策略或算法,我们可以重用它们。
- 在状态模式中,每个状态通过持有Context的引用,来实现状态转移;但是每个策略都不持有Context的引用,它们只是被Context使用。
本文转载自: 掘金