Head First 设计模式 —— 12. 状态 (State

2021-01-15  本文已影响0人  满赋诸机

思考题

public class GumballMachine {
    final static int SOLD_OUT = 0;
    final static int NO_QUARTER = 1;
    final static int HAS_QUARTER = 2;
    final static SOLD = 3;
    
    int state = SOLD_OUT;
    int count = 0;
    
    public GumballMachine(int count) {
        this.count = count;
        if(count > 0) {
            state = NO_QUARTER;
        }
    }
    
    public void insertQuarter() {
        if(state == HAS_QUARTER) {
            // print error message
        } else if(state == NO_QUARTER) {
            state = HAS_QUARTER;
            // print success message
        } else if(state == SOLD_OUT) {
            // print error message
        } else if(state == SOLD) {
            // print error message
        }
    }
    
    public void ejectQuarter() {
        // ...
    }
    
    public void turnCrank() {
        // ...
    }
    
    public void dispense() {
        // ...
    }
}

下列哪一项描述了我们实现的状态?(多选) P396

思考题

public class GumballMachine {
    State soldOutState;
    State noQuarterState;
    State hasQuarterState;
    State soldState;
    
    State state = soldOutState;
    int count = 0;
    
    public GumballMachine(int numberGumballs) {
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        this.count = numberGumballs;
        if (numberGumballs > 0) {
            state = noQuarterState;
        }
    }
    
    public void insertQuarter() {
        state.insertQuarter();
    }
    
    public void ejectQuarter() {
        state.ejectQuarter();
    }
    
    public void turnCrank() {
        state.turnCrank();
        state.dispense();
    }
    
    void setState(State state) {
        this.state = state;
    }
    
    void releaseBall() {
        // print success message
        if(count != 0) {
            count = count - 1;
        }
    }
}

让我们来回头看看糖果机的实现。如果曲柄被转动了,但是没有成功(比方说顾客没有先投入25分钱的硬币)。在这种情况下,尽管没有必要,但我们还是会调用 dispense() 方法。对于这个问题你要如何修改呢? P405

状态模式

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

12. 状态模式

特点

缺点

状态模式和策略模式的区别

状态模式

策略模式

思考题

应该由状态类还是上下文决定状态转换的流向? P412

思考题

我们需要你为糖果机写一个重填糖果的 refill() 方法。这个方法需要一个变量——所要填入机器中的糖果数目。它应该能更新糖果机内的糖果数目,并重设机器的状态。 P421

void refill(int num) {
    this.count += num;
    if(state instanceof SoldOutState) {
        state = noQuarterState;
    }
}

思考题

配对下列模式和描述: P422
状态模式:封装基于状态的行为,并将行为委托到当前状态
策略模式:将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为
模板方法模式:由子类决定如何实现算法中的某些步骤

上一篇下一篇

猜你喜欢

热点阅读