状态模式
模式定义
状态模式允许对象在内部状态改变时改变其行为,并且,此改变对于客户端透明。状态模式将不同状态下的对象行为进行解耦。该模式在GOF95中被分类为行为模式。
模式结构与说明
- Context 是一个类,它可以拥有一些内部状态,这些状态使用 State 接口表示
- 不管何时,Client调用 Context.request() 方法时,Context都将该调用委托给 State 对象处理
- State 规定了所有具体状态的公共接口,这样确保了状态之间可以互相替换
- ConcreteState 处理来自 Context 的请求,每个 ConcreteState 都提供了它自己对于请求处理的实现
- ConcreteState 处理完请求后,可能导致 Context 的状态发生改变,单这需要前者持有后者的引用
需要注意的是, State 对象包含的方法数量取决于状态机支持的操作的数量,具体状态的数量则取决于状态机包含的状态的数量。
状态转换可能由 ConcreteState 驱动,也可能由 Context 驱动,如果状态转换规则是动态的,则倾向于在 ConcreteState 中完成状态转换。状态转换绝不会有客户代码驱动。
状态模式的优点:
- 简化应用逻辑控制,避免了庞大的if-else结构
- 更好的分离了状态与行为
状态模式的缺点:
- 由于每个状态引入一个 ConcreteState ,可能导致程序中出现太多的状态类,显得混乱
- 违反了OCP,当新的操作引入后,所有状态类都要修改,以支持该操作
状态模式的适用时机:
- 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为
- 一个操作中含有庞大的分支条件语句,且这些分支依赖于该对象的状态
经典应用
JSF中的状态模式
javax.faces.lifecycle.LifeCycle实现了状态模式,其 execute() 方法的行为取决于JSF生命周期的当前阶段(即状态)。
模式演变
- 与策略模式的比较:状态模式与策略模式的类图完全一样,但是两个模式的意图和用法都不同。策略模式允许客户端根据需要动态切换算法;状态模式的状态对象则是不允许客户感知的,状态的变化由客户请求的操作驱动,属于模式内部处理部分
Leave a Reply