天天看點

設計模式--狀态模式

類圖

設計模式--狀态模式

源碼

ATM.java
package com.state;


public class ATM {
    /*所有狀态*/
    private ATMState readyState;
    private ATMState noCashState;
    private ATMState noServiceState;
 
    private ATMState currState;//目前狀态
    private int totalAmount;//賬戶現鈔總數
 
    /*測試用的臨時變量*/
    private String pwd;//密碼
    private int balance;//餘額
    private int amount;//取款金額
 
    public ATM(int totalAmount, int balance, int amount, String pwd) throws Exception{
        //初始化所有狀态
        readyState = new ReadyState(this);
        noCashState = new NoCashState(this);
        noServiceState = new NoServiceState(this);
 
        if(totalAmount > 0){
            currState = readyState;
        }
        else if(totalAmount == 0){
            currState = noCashState;
        }
        else{
            throw new Exception();
        }
 
        //初始化測試資料
        this.totalAmount = totalAmount;
        this.balance = balance;
        this.amount = amount;
        this.pwd = pwd;
    }
 
    /*把具體行為委托給狀态對象*/
    /**
     * 插卡
     */
    public void insertCard(){
        currState.insertCard();
    }
 
    /**
     * 送出密碼
     */
    public void submitPwd(){
        currState.submitPwd();
    }
 
    /**
     * 取款
     */
    public void getCash(){
        currState.getCash();
    }
 
    /**
     * 查詢餘額
     */
    public void queryBalance(){
        currState.queryBalance();
    }
 
    /**
     * 取卡
     */
    public void ejectCard(){
        currState.ejectCard();
    }
    public String toString(){
        return "賬戶總額¥" + totalAmount;
    }
    public String SKT() {
        if(totalAmount >= 0) {
            return  "賬戶狀态為綠色正常狀态,既可以存,也可以取款";
        }
        if(totalAmount >= -1000 && totalAmount < 0) {
            return "賬戶狀态為藍色欠費狀态,既可以存,也可以取款";
        }
        if(totalAmount < -1000) {
            return "賬戶狀态為紅色透支狀态,隻能存款";
        }
        return "";
    }
 
    /*此處略去大量getter and setter*/
 
    public String getPwd(){
        return pwd;
    }
    public int getBalance() {
        return balance;
    }
    public int getTotalAmount() {
        return totalAmount;
    }
    public int getAmount() {
        return amount;
    }
 
    public void setTotalAmount(int totalAmount) {
        this.totalAmount = totalAmount;
    }
 
    public void setBalance(int balance) {
        this.balance = balance;
    }
 
    public ATMState getNoCashState() {
        return noCashState;
    }
 
    public void setCurrState(ATMState currState) {
        this.currState = currState;
    }
}

ATMState.java

package com.state;

public interface ATMState {
    public abstract void insertCard();
    public abstract void submitPwd();
    public abstract void getCash();
    public abstract void queryBalance();
    public abstract void ejectCard();
}


NoCashState.java

package com.state;

public class NoCashState implements ATMState{
    private ATM atm;//保留狀态持有者的引用,以便對其進行操作
 
    public NoCashState(ATM atm){
        this.atm = atm;
    }
 
    @Override
    public void insertCard() {
        System.out.println("插卡完成");
    }
 
    @Override
    public void submitPwd() {
        System.out.println("密碼送出完成");
        //驗證密碼并做相應處理
        if("123".equals(atm.getPwd())){
            System.out.println("密碼驗證通過");
        }
        else{
            System.out.println("密碼驗證失敗");
            //彈出卡片
            ejectCard();
        }
    }
 
    @Override
    public void getCash() {
        System.out.println("取款失敗,機内無鈔");
    }
 
    @Override
    public void queryBalance() {
        System.out.println("賬戶餘額¥" + atm.getBalance());
        System.out.println("賬戶餘額查詢完成");
    }
 
    @Override
    public void ejectCard() {
        System.out.println("取卡完成");
    }
}

NoServiceState.java

package com.state;

public class NoServiceState implements ATMState{
    private ATM atm;//保留狀态持有者的引用,以便對其進行操作
 
    public NoServiceState(ATM atm){
        this.atm = atm;
    }
 
    @Override
    public void insertCard() {
        System.out.println("插卡失敗,機器發生了故障");
    }
 
    @Override
    public void submitPwd() {
        System.out.println("密碼送出失敗,機器發生了故障");
    }
 
    @Override
    public void getCash() {
        System.out.println("取款失敗,機器發生了故障");
    }
 
    @Override
    public void queryBalance() {
        System.out.println("餘額查詢失敗,機器發生了故障");
    }
 
    @Override
    public void ejectCard() {
        System.out.println("取卡失敗,機器發生了故障");
    }
}

ReadyState.java

package com.state;


public class ReadyState implements ATMState{
    private ATM atm;//保留狀态持有者的引用,以便對其進行操作
    public ReadyState(ATM atm){
        this.atm = atm;
    }
 
    @Override
    public void insertCard() {
        System.out.println("插卡完成");
    }
    @Override
    public void submitPwd() {
        System.out.println("密碼送出完成");
        //驗證密碼并做相應處理
        if("6300".equals(atm.getPwd())){
            System.out.println("密碼驗證通過");
        }
        else{
            System.out.println("密碼驗證失敗");
            //彈出卡片
            ejectCard();
        }
    }
 
    @Override
    public void getCash() {
        //atm.getTotalAmount() >= atm.getAmount() && atm.getBalance() >= atm.getAmount()
        if(atm.getTotalAmount() != 9999){
            //更新賬戶餘額
            atm.setBalance(atm.getBalance() - atm.getAmount());
            //更新機内現鈔總數
            atm.setTotalAmount(atm.getTotalAmount() - atm.getAmount());
            System.out.println("吐出¥" + atm.getAmount());
            System.out.println("取款完成");
            //彈出卡片
            ejectCard();
            //檢查機内餘鈔
            if(atm.getTotalAmount() == 0){//若無鈔,切換到NoService狀态
                atm.setCurrState(atm.getNoCashState());
                System.out.println("無鈔資訊已經發送至銀行");
            }
        }
        else{
            System.out.println("取款失敗,餘額不足");
            //彈出卡片
            ejectCard();
        }
    }
 
    @Override
    public void queryBalance() {
        System.out.println("餘額¥" + atm.getBalance());
        System.out.println("餘額查詢完成");
    }
 
    @Override
    public void ejectCard() {
        System.out.println("取卡完成");
    }
}


Client.java

package com.state;

public class Client {
    public static void main(String[] args) {
        
        try {
            test(1000, 500, 200, "6300");
            System.out.println("------------------------------------------------------------");
            test(1000, 300, 500, "6300");
            System.out.println("------------------------------------------------------------");
         
        } catch (Exception e) {
            System.out.println("賬戶餘額小于-1000,賬戶狀态為紅色透支狀态,請存錢後再取");
            //System.out.println("機器故障,維修請求已經發送至維修方");
        }
    }
 
    private static void test(int totalAmount, int balance, int amount, String pwd)throws Exception{
        //建立ATM
        ATM atm;
        atm = new ATM(totalAmount, balance, amount, pwd);
        //輸出初始狀态
        System.out.println(atm.toString());
        System.out.println(atm.SKT());
        atm.insertCard();
        atm.submitPwd();
        atm.getCash();
        //輸出結束狀态
        System.out.println(atm.toString());
    }
}      

測試截圖

設計模式--狀态模式