状态模式

来源:互联网 发布:淘宝球鞋店 编辑:程序博客网 时间:2024/06/08 09:54

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

这里写图片描述

我们以一个自动糖果贩卖机为例。机器共有4个状态,分别为已投币,未投币,糖果售空,发放糖果,每个状态都需要维护4种行为,分别为投币、退币、转动曲柄、发放糖果。并且状态之间可以相互转换,例如由未投币状态转换为已投币状态等等。

1. 糖果机

public class GumballMachine {    private State soldState;    private State noQuarterState;    private State hasQuarterState;    private State soldOutState;    private State state;    private int count = 0;    public GumballMachine(int count) {        super();        this.count = count;        this.soldState = new SoldState(this);        this.soldOutState = new SoldOutState(this);        this.noQuarterState = new NoQuarterState(this);        this.hasQuarterState = new HasQuarterState(this);        if(count > 0){            this.state = noQuarterState;        }else{            this.state = soldOutState;        }    }    public void insertQuarter(){        state.insertQuarter();    }    public void ejectQuarter(){        state.ejectQuarter();    }    public void tumCrank(){        state.tumCrank();    }    public void dispense(){        state.dispense();    }    public void releaseBall() {        System.out.println("A gumball comes rolling out the slot...");        if (count != 0) {            count--;        }    }    public State getSoldState() {        return soldState;    }    public void setSoldState(State soldState) {        this.soldState = soldState;    }    public State getNoQuarterState() {        return noQuarterState;    }    public void setNoQuarterState(State noQuarterState) {        this.noQuarterState = noQuarterState;    }    public State getHasQuarterState() {        return hasQuarterState;    }    public void setHasQuarterState(State hasQuarterState) {        this.hasQuarterState = hasQuarterState;    }    public State getSoldOutState() {        return soldOutState;    }    public void setSoldOutState(State soldOutState) {        this.soldOutState = soldOutState;    }    public State getState() {        return state;    }    public void setState(State state) {        this.state = state;    }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }    @Override    public String toString() {        return "the machine has " + count + " gumballs";    }}

2. 状态接口

public interface State {    /**     * 投币     */    void insertQuarter();    /**     * 退币     */    void ejectQuarter();    /**     * 转动曲柄     */    void tumCrank();    /**     * 发放糖果     */    void dispense();}

3. 未投币状态

public class NoQuarterState implements State{    private GumballMachine gumballMachine;    public NoQuarterState(GumballMachine gumballMachine) {        super();        this.gumballMachine = gumballMachine;    }    public void insertQuarter() {        //转换为已投币状态        System.out.println("You inserted a quarter");        gumballMachine.setState(gumballMachine.getHasQuarterState());    }    public void ejectQuarter() {        //未投币不能退币        System.out.println("You haven't inserted a quarter");    }    public void tumCrank() {        //未投币不能转动曲柄        System.out.println("You turned, but there's no quarter");    }    public void dispense() {        //未投币不能发放糖果        System.out.println("You need pay first");    }}

4. 已投币状态

public class HasQuarterState implements State{    private GumballMachine gumballMachine;    public HasQuarterState(GumballMachine gumballMachine) {        super();        this.gumballMachine = gumballMachine;    }    public void insertQuarter() {        //已投币不能再投币        System.out.println("You can't insert another quarter");    }    public void ejectQuarter() {        //将状态转换为未投币        System.out.println("Quarter returned");        gumballMachine.setState(gumballMachine.getNoQuarterState());    }    public void tumCrank() {        //转动曲柄将状态转为发放糖果        System.out.println("You turned...");        gumballMachine.setState(gumballMachine.getSoldState());    }    public void dispense() {        //已投币尚未转动曲柄不能发放糖果        System.out.println("No gumball dispend");    }}

5. 发放糖果状态

public class SoldState implements State{    private GumballMachine gumballMachine;    public SoldState(GumballMachine gumballMachine) {        super();        this.gumballMachine = gumballMachine;    }    public void insertQuarter() {        //不能再次投币        System.out.println("Please wait, we're already giving you a gumball");    }    public void ejectQuarter() {        //不能退币        System.out.println("Sorry, you already turned crank");    }    public void tumCrank() {        //不能再次转动曲柄        System.out.println("Turning twice doesn't get you another gumball");    }    public void dispense() {        //发放糖果        gumballMachine.releaseBall();        if(gumballMachine.getCount() > 0){            //糖果数量大于0 将状态转为未投币            gumballMachine.setState(gumballMachine.getNoQuarterState());        }else{            //糖果数量为0 将状态转为售空            System.out.println("Oops, out of gumballs");            gumballMachine.setState(gumballMachine.getSoldOutState());        }    }}

6. 售空状态

public class SoldOutState implements State{    private GumballMachine gumballMachine;    public SoldOutState(GumballMachine gumballMachine) {        super();        this.gumballMachine = gumballMachine;    }    public void insertQuarter() {        //售空不能投币        System.out.println("You can't insert a quarter, the machine is sold out");    }    public void ejectQuarter() {        //售空不能退币        System.out.println("you can't eject, you haven't inserted a quarter yet");    }    public void tumCrank() {        //售空不能转动曲柄        System.out.println("You turned, but there is no gumballs");    }    public void dispense() {        //售空不能发放糖果        System.out.println("No gumball dispensed");    }}

7. 测试

public class StateTest {    public static void main(String[] args) {        GumballMachine gumballMachine = new GumballMachine(5);        System.out.println(gumballMachine);        gumballMachine.insertQuarter();    }}

8. 运行结果

the machine has 5 gumballsYou inserted a quarter