我们今天开门见山吧,我们又接到了一个新的项目,让我们看看这次的项目是什么吧
对于大家学了熟练的开发技巧,看到这么一个项目,是不是内心第一个想法就是------真TM简单。
public class GumballMachine {因为代码比较明白,就不写入注释,方法也就写了其中一种,另外三个行为这里就省略的,毕竟重点不是这种直接的设计方法。
final static int SOLD_OUT = 0;
final static int NO_QUARTER = 1;
final static int HAS_QUARTER = 2;
final static int 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) {
System.out.println("You can't insert another quarter");
} else if (state = NO_QUARTER) {
state = HAS_QUARTER;
System.out.println("You inserted a aquarter");
} else if (state = SOLD_OUT) {
System.out.println("You can't insert a quarter , the machine if sold out");
} else if (state = SOLD) {
System.out.println("Please wait, we're already giving you'a gumball");
}
}
}
我们把这个项目交给公司后,公司的CEO又提出了新的需求,是什么呢?
恕我直言,这个要求真的是无语,没办法,毕竟是需求方的要求,只能帮他们实现了,这个时候,就发现我们之前写的代码不怎么易于维护和修改了吧,这个时候我们就需要重新构造他了。
然后我们通过接口定义,设计了一个新的类图:
让我们实现上面这个模式吧。(这里的类图少了一个WinnerState类,就是成功的能有两颗糖,不要在意,我们会在下面的代码中实现的)
State类:
public interface State {GumballMachine类:
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
public class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
//以上是所有的状态
State state = soldOutState; //追踪当前状态
int count = 0; //记录糖果数
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense(); //我们不需要单独实现dispense方法,可以把这个方法写入turnCrank里面
}
public void setState (State state) {
this.state = state;
}
public void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count = count - 1;
}
}
public State getSoldOutState() {
return soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public State getSoldState() {
return soldState;
}
public State getWinnerState() {
return winnerState;
}
public State getState() {
return state;
}
public int getCount() {
return count;
}
}
HasQuarterState类:public class HasQuarterState implements State {WinnerState类:
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
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 turnCrank() {
System.out.println("You turned..");
gumballMachine.setState(gumballMachine.getSoldState());
}
public void dispense() {
System.out.println("No gumball dispensed");
}
}public class WinnerState implements State {定义状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
GumballMachine gumballMachine;
public WinnerState(GumballMachine gumballMachine) {
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 the crank");
}
public void turnCrank() {
System.out.println("Turning twice doesn't get you another gumball");
}
public void dispense() {
System.out.println("You're a winner ! you get two gumballs for your quarter");
gumballMachine.releaseBall();
if (gumballMachine.getCount() == 0) {
gumballMachine.setState(gumballMachine.getSoldOutState());
} else {
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
}状态模式的类图:
这个类图是不是很熟悉,对,他和策略模式的类图是一样的,他们有什么区别的,让我们来看看吧。
总结:
1:状态模式允许一个对象基于内部状态而拥有不同的行为。
2:状态模式用类代表状态。
3:通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。
4:状态模式和策略模式有相同的类图,但是他们的意图不一样。
5:使用状态模式通常会导致设计中类的数目大量增加。