head first Design Pattern State

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。将每种状态封装成独立的类,并将动作委托给代表当前状态的对象,当糖果机处于不同的状态时,你投入25¥会得到不同的行为。
策略模式是除了继承之外一种弹性替代方案,通过组合不同的对象来改变行为。
状态模式是不用在context中放置许多条件判断的替代方案,通常将行为包装进状态中,通过在context中简单的改变状态对象来改变context的行为。
状态的改变可以放在context中也可以放在状态类中控制,而且状态类可以被多个Context实例共享,前提是状态对象不能持有他们自己的内部状态,否则不能共享。想要共享状态,需要把每个状态都指定到静态的实例变量中。状态模式会导致类的数目大增。

public class GumballMachine {
//all the states of a machine
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;

//there is no candy in the machine at the beginning
State state = soldOutState;

int count = 0; // count for the number of candy

public GumballMachine(int numberGumballs) {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(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();   
}
public State getHasQuarterState() {
// TODO Auto-generated method stub
return hasQuarterState;
}

public void setState(State state) {
// TODO Auto-generated method stub
this.state = state;
}

void releaseBall(){
System.out.println("A gumball comes rolling out of slot...");
if (count != 0) {
count = count-1;
}
}

public State getNoQuarterState() {
// TODO Auto-generated method stub
return noQuarterState;
}

public State getSoldOutState() {
return soldOutState;
}

public State getSoldState() {
return soldState;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public State getWinnerState() {
// TODO Auto-generated method stub
return winnerState;
}

}
//所有状态的接口,里面包括状态转移的方法
public interface State {
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();   
}

public class SoldState implements State {
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}

@Override
public void dispense() {
// TODO Auto-generated method stub
gumballMachine.releaseBall();
if (gumballMachine.getCount()>0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}

@Override
public void ejectQuarter() {
// TODO Auto-generated method stub
System.out.println("sorry, you already turned the crank");
}

@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("Please wait, we're already giving you a gumball");
}

@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("Turning the crank twice doesn't get you another gumball!");
}

}
//implement the state which there is no 25$ in the machine
public class NoQuarterState implements State{
GumballMachine gumballMachine;

public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}

@Override
public void dispense() {
// if there is no money
System.out.println("You need to pay first!");
}

@Override
public void ejectQuarter() {
// 没有给钱就不能退钱
System.out.println("You haven't insert a quarter");
}

@Override
public void insertQuarter() {
// 接收25$然后改变状态为HasQuarterState
System.out.println("You insert a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}

@Override
public void turnCrank() {
// 没给钱就没有糖果
System.out.println("You turned, but there's no quarter");
}

}

posted @ 2010-05-27 05:47  莫忆往西  阅读(181)  评论(0编辑  收藏  举报