设计模式之状态模式
状态模式,属于行为型设计模式,用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。
定义:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
问题描述:当一个对象存在多个状态,并且这些状态之间可以进行转换,而且对象在不同状态下的行为也不同,那么如何去实现这样的功能呢?
解决方案:将这个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,客户端无需关心对象状态的转换以及对象所处的当前状态和行为,无论对于何种状态的对象,客户端都可以一致处理。
结构图:
举个栗子:讲一个银行信用卡的故事。。。
银行信用卡,假设账户存在三种状态:
(1)余额大于0时,账户为正常状态,可存款也可取款;
(2)余额在-2000~0之间时,账户为透支状态,可存款也可取款,但是需要计算利息;
(3)余额小于-2000时,账户为受限状态,用户只能存款,不能取款,又需要计算利息。
根据余额的不同,账户有着不同的状态,不同的状态又有着不同的行为,状态之间可发生相互转换。具体实现如下:
1. 新建一个环境类Account,它拥有多种状态的对象。代码如下:
2. 新建一个抽象状态类AccountState,封装了一个特定状态的相关行为,声明了不同状态对应的方法。代码如下:
3. 分别新建三个不同的状态类,每个状态类实现一个与环境类的一个状态的相关行为。代码如下:
4. 设置不同的余额,表现账户在三种不同的状态下的行为。代码如下:
5. 运行后的效果,如图所示:
综上所述,状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中,通过设置不同的状态对象可以让环境对象拥有不同的行为,而状态转换的细节对于客户端而言是透明的,方便了客户端的使用。
优点:
1. 在环境类或具体状态类中封装了状态的转换规则,可以对状态转换代码进行集中管理;
2. 将状态转换逻辑与状态对象合成一体,避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。
缺点:
1. 会增加类和对象的个数,导致系统运行开销大;
2. 不符合开闭原则,当增加一个新的状态类时需要修改那些负责状态转换的源代码,否则无法转换到新增状态。
适用场景:
1. 当对象的行为受到状态的影响时;
2. 存在大量与对象状态有关的条件语句时。