Technology-设计模式-状态模式

本文介绍了GoF中的状态模式。

模式推演

针对复杂的状态机:

当我们在处理一个有着复杂状态转换的对象时,例如糖果机有着以下的状态:

1
SOLD_OUT, NO_QUARTER, HAS_QUARTER, SOLD

那么我们在客户投入硬币时,方法为:

1
2
3
4
5
6
7
8
9
10
11
public void insertIcon(){
if(state == HAS_QUARTER){
...
}else if(state == NO_QUARTER){
...
}else if(state == HAS_QUARTER){
...
}else if(state == SOLD){
...
}
}

当糖果机有新的状态时,我们必须修改糖果机所有的方法,以及里面冗长的if语句,显然,并没有把变化封装。

封装变化

为了将变化封装,我们注意到状态state是一个变化点,因此,我们构造State抽象接口,让其子类自己来控制状态转换,这样,新增状态时,我们只需要新增一个子类即可。

Technology-DesignPattern-State-Modify

另外,不用写冗长的if语句来判断状态,而是直接针对操作进行对应的状态切换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HasQuarterState implements State {
GumballMachine gumballMachine;

public HasQuarterState(GumballMachine gumballMachine){
this. gumballMachine = gumballMachine;
}

public insertQuarter(){
}

public ejeckQuarter(){
gumballMachine.setState(gumballMachine.getNoQuarterState());
}

public turnCrank(){
}

public dispense(){
}
}

定义

状态模式(State Pattern):允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

其中“对象看起来好像修改了它的类”,是指从客户角度来看,对象完全改变了行为,好像是从新的类实例化,其实并没有,只是利用组合通过简单引用不同的状态对象来造成类改变的假象。

类图:

Technology-DesignPattern-Composite-Class

状态模式与策略模式的区别:类图是一样的,但是对于客户而言,状态模式的状态是内部控制的,客户察觉不到,而策略模式的算法替换是由客户指定的。