設計模式系列之十二狀態模式

weixin_34402408發表於2016-12-24

  舉一個自動取款機的場景來說明狀態模式的使用。去自動提款機取錢首先得有插卡的動作,最後還會有取卡的動作。對應兩個狀態,一個是無卡狀態,另外一個是有卡狀態。

一、程式碼實現

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,越到後面程式碼將越來越難以維護。

二、使用狀態模式改造

//狀態介面
public interface State {
    //插入卡片
    public void insertCard();
    //取出卡片
    public void quitCard();
}
//無卡狀態
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("你沒有插入銀行卡");
    }
}
//有卡狀態
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);
    }
}
//使用狀態模式改造後的業務程式碼
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狀態判斷。當有業務變更,或是新狀態加入時可靈活的調整程式碼。

系列文章:
<a href="http://muchstudy.com/2016/11/27/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%B8%80%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/">設計模式系列之一單例模式</a>
<a href="http://muchstudy.com/2016/11/28/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%BA%8C%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/">設計模式系列之二策略模式</a>
<a href="http://muchstudy.com/2016/11/29/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%B8%89%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/">設計模式系列之三觀察者模式</a>
<a href="http://muchstudy.com/2016/12/02/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%9B%9B%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F/">設計模式系列之四裝飾者模式</a>
<a href="http://muchstudy.com/2016/12/06/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%BA%94%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/">設計模式系列之五工廠模式</a>
<a href="http://muchstudy.com/2016/12/10/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%85%AD%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F/">設計模式系列之六命令模式</a>
<a href="http://muchstudy.com/2016/12/17/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%85%AB%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F/">設計模式系列之八外觀模式</a>
<a href="http://muchstudy.com/2016/12/14/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%B8%83%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F/">設計模式系列之七介面卡模式</a>
<a href="http://muchstudy.com/2016/12/17/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%B9%9D%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F/">設計模式系列之九模板方法模式</a>
<a href="http://muchstudy.com/2016/12/20/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%8D%81%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F/">設計模式系列之十迭代器模式</a>
<a href="http://muchstudy.com/2016/12/21/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%8D%81%E4%B8%80%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F/">設計模式系列之十一組合模式</a>

相關文章