title: 事物的状态-状态模式
date: 2018-09-05 16:11:35
categories:
- 工作
tags: - Java
前段时间看到有代码在用状态机,而这段时间重温软件设计模式,刚好有状态模式,记录一下。
场景:
对于一个自动售卖机的小系统,往往会有,投币、售出、售罄、退钱等状态。状态之间需要转换,才能完成一系列操作,实现某一个完整的功能。
糟糕的解决方案
旧的解决方案是怎样的呢?
首先,用常量定义出所有状态。
在进行操作时,用if判断当前状态是否是定义出来的某个状态,然后进行相应的操作。同时进行状态的切换。
问题点:
用上述方法解决的问题,会有如下痛点:
- 扩展性极差,如果新增一个状态,需要变动原有逻辑代码,严重违反【对扩展开放】的原则。
- 随着时间流逝,主流程出现大量的if判断,导致某个方法过于庞大,不利于阅读维护。
- 完全是面向过程思维方式,不是面向对象的思考方式。
改良的解决方案
切入点:将每个状态的行为放在对应的状态类中,每个状态只要实现自己的动作就可以了。
思路:
- 定义一个状态接口(or 抽象类)。每个动作在接口中都有对应的方法。
- 每个具体的状态实现状态接口,并负责自己当前状态下各个方法的实现,eg:售出状态的退钱方法,取东西方法等。
- 最后,主流程里将动作委托给对应的状态类。
类图如下
如图1状态模式类图所示,State是定义状态动作的接口,ConcreteStateA与ConcreteStateB是接口State的具体状态。Context是上下文中进行调用,调用State.handle方法,用多态代替了if。
在具体使用过程中,ConcreteStateA与ConcreteStateB或其他状态可以相互转换,也可以在Context中转换。同时,当遇到拓展时,比如新增状态ConcreteStateC,只需要新增ConcreteStateC实现State接口,完成handle,并在Context里进行调用。