设计模式系列之十二状态模式

  举一个自动取款机的场景来说明状态模式的使用。去自动提款机取钱首先得有插卡的动作,最后还会有取卡的动作。对应两个状态,一个是无卡状态,另外一个是有卡状态。

一、代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ATM {
final static int NO_CARD = 0;
final static int HAVE_CARD = 1;
//提款机初始状态为无卡
int state = NO_CARD;

//插卡
public void insertCard(){
if(state==NO_CARD){
System.out.println("插入卡片");
//设置状态为有卡状态
setState(HAVE_CARD);
}else if(state==HAVE_CARD){
System.out.println("已插入银行卡");
}
}

//取卡
public void quitCard(){
if(state==NO_CARD){
System.out.println("你没有插入银行卡");
}else if(state==HAVE_CARD){
System.out.println("退出卡片");
//设置状态为无卡状态
setState(NO_CARD);
}
}

public void setState(int state){
this.state = state;
}
}

  从上面的代码可以预见到,如果再增加状态,那么对应的操作里面就需要增加一组if-else,越到后面代码将越来越难以维护。

二、使用状态模式改造

1
2
3
4
5
6
7
//状态接口
public interface State {
//插入卡片
public void insertCard();
//取出卡片
public void quitCard();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//无卡状态
public class NoCard implements State{
NewATM atm;
public NoCard(NewATM newATM){
this.atm = newATM;
}

@Override
public void insertCard() {
System.out.println("插入卡片");
atm.setState(NewATM.HAVE_CARD);
}

@Override
public void quitCard() {
System.out.println("你没有插入银行卡");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//有卡状态
public class HaveCard implements State{
NewATM atm;
public HaveCard(NewATM newATM){
this.atm = newATM;
}

@Override
public void insertCard() {
System.out.println("已插入银行卡");
}

@Override
public void quitCard() {
System.out.println("退出卡片");
atm.setState(NewATM.NO_CARD);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//使用状态模式改造后的业务代码
public class NewATM {
static State NO_CARD;
static State HAVE_CARD;

private State state = NO_CARD;

public NewATM(){
NO_CARD = new NoCard(this);
HAVE_CARD = new HaveCard(this);
}
//插卡
public void insertCard(){
state.insertCard();
}

//取卡
public void quitCard(){
state.quitCard();
}

public void setState(State state){
this.state = state;
}
}

  经过改造,彻底干掉了繁琐的if-else状态判断。当有业务变更,或是新状态加入时可灵活的调整代码。

系列文章:
设计模式系列之一单例模式
设计模式系列之二策略模式
设计模式系列之三观察者模式
设计模式系列之四装饰者模式
设计模式系列之五工厂模式
设计模式系列之六命令模式
设计模式系列之八外观模式
设计模式系列之七适配器模式
设计模式系列之九模板方法模式
设计模式系列之十迭代器模式
设计模式系列之十一组合模式

留言

欢迎交流想法。留言会通过 GitHub Issues 保存,首次使用需要登录 GitHub。