举一个自动取款机的场景来说明状态模式的使用。去自动提款机取钱首先得有插卡的动作,最后还会有取卡的动作。对应两个状态,一个是无卡状态,另外一个是有卡状态。
一、代码实现
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。