状态模式
标签(空格分隔): 设计模式
行为型模式。
类的行为是基于它的状态改变的,状态改变,行为跟着改变。
具体实现:
一个状态接口,具体状态类实现该接口。
一个Context类,拥有状态的实例,随着这个状态的改变,它的行为会改变。
注重状态的转变,状态只能从一个状态转变按规则转变成另一个状态,而不是任意转换。例如房间只能从未预订变成预订。
类图结构
角色:
环境类(Context): 定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。
抽象状态类(State): 定义一个接口以封装与Context的一个特定状态相关的行为。
具体状态类(ConcreteState): 每一子类实现一个与Context的一个状态相关的行为。
把状态封装成一个类,状态的改变只需要传入不同的具体state实现即可。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
State模式将所有与一个特定的状态相关的行为都放入一个对象(具体state)中。
应用场景:
- 电灯开关,按一下,状态变成开灯,再按一下,状态变成关灯。
- 网上投票,投一次,正常。再投,变成反复投票。再投,取消当次投票资格。再投,系统拉黑,以后再也不能投。
- 酒店订房系统,房间有预订、入住、退订、退房多种状态。
优点:
新增状态时,必定会增加状态相应的行为,使用状态模式不用为新状态增加很多if else判断,只需要写一个新类实现State接口,然后将状态改成新状态即可。Context会跟据新状态的具体实现来改变行为。
状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求。
状态模式和策略模式一个很重要的区别,状态模式的行为是平行性的,不可相互替换的;而策略模式的行为是平等性的,是可以相互替换的。