State Pattern
Title | Module | Category | Tags | ||
---|---|---|---|---|---|
State
|
state-design
|
Behavioral
|
|
状态模式简介
状态模式, 也称状态机模式, 允许对象在内部状态发生改变时改变它的行为, 对象看起来似乎修改了它的类, 属于行为型模式. 状态模式中类的行为是由状态决定的, 不同的状态下有不同的行为. 其目的是让一个对象在其内部改变的时候, 其行为也随之改变. 核心在于状态与行为绑定, 不同的状态对应不同的行为.
结构图

从 UML 类图来看 , 状态模式包含三种角色:
- 上下文环境(Context): 定义 Client 端的接口, 内部维护一个当前状态实例, 并负责具体状态的切换
- 抽象状态(State): 定义该状态下的行为
- 具体状态(ConcreteState): 具体实现该状态对应的行为, 并在需要的情况下进行状态切换
应用场景
状态模式存在于生活中, 例如网购的订单状态变化, 电梯状态等等.
软件研发设计中, 对于某项操作, 可能存在不同的情况. 通常处理多 Case 最直接的方式是采用 if ... else
或是 switch ... case
条件语句进行枚举. 但这种做法存在弊端: 条件判断语句, 可读性差, 且不具备扩展性, 维护复杂度高. 而如果将不同状态独立起来用各个不同的类进行表示, 建立状态 - 对象处理逻辑的映射关系, 具备良好的扩展能力.
状态模式主要解决当控制一个对象状态的条件表达式过于复杂的情况. 通过将状态的判断逻辑转移到表示不同状态的一些列类中, 简化复杂判断逻辑的处理. 对象行为依赖于它的属性状态, 会根据它的状态改变而改变它的对应行为. 状态模式适用于如下场景:
- 行为随状态改变而改变的场景
- 单个操作包含多个分支结构, 且分支逻辑与对象状态相关联
代码示例
根据 UML 图进行 Demo 案例设计, 记录在 Here 了: D.
思考总结
状态模式相较责任链模式, 策略模式由着相似之处, 主要可以从应用场景, 设计实现角度作一些分析:
-
状态模式 vs 责任链模式
两者都能够解决
if
判断分支冗余问题. 定义角度来说, 责任链模式强调的是外部节点对象间的改变, 而状态模式核心在于对一个对象内在状态的改变; 用例设计方面, 区别在于状态模式各个状态对象知道下一阶段的状态对象, 而责任链模式并不清楚下一节点处理对象, 链式的组装由客户端负责. -
状态模式 vs 策略模式
状态模式和策略模式的 UML 类图相似, 但两者的应用场景不一样. 状态模式各个状态之间存在相互关系, 彼此之间在特定条件下存在自动切换状态的效果, 用户 Client 端无法指定状态, 只能设定初始状态. 相对而言, 策略模式多种行为算法策略选择一种即可满足特定场景, 彼此之间属于是独立的, 用户 Client 端可以自行切换状态效果.
优点
- 状态类的职责分明, 具备可扩展性
- 结构脉络分明, 独立出各种状态, 可维护性得到增强
- 状态可读性强, 状态转换目的更加明确
缺点
- 一项事物的状态种类需要作评估, 否则会造成状态类的膨胀, 程序结构和代码的混乱
- 设计原则角度来看, 当面临新增状态类, 可能会修改已有的负责状态转换的相关类.
Reference
- E.Gamma, R.Helm, R.Johnson, and Vlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley, 1995
- State Pattern on Wiki