状态模式允许对象在对象内部状态改变时改变它的行为,对象看起来好像修改了他的类
现在又一个糖果机,我们需要写程序来控制它的出售行为,如图
当然我们可以用一堆if,else语句俩控制它。但是如果程序需要加入其他的状态,那么整个程序就会变得越来越乱。这时我们需要状态模式来重构程序。
java代码
// 状态接口
public interface State {
void insertCoin();
void ejectCoin();
void turnCrank();
void dispense();
}
// 没有投币状态
public class NoCoinState implements State {
private GumballMachine machine;
public NoCoinState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertCoin() {
machine.setState(machine.getHasCoinState());
System.out.println("Your inserted a coin");
}
@Override
public void ejectCoin() {
System.out.println("Your have not inserted a coin");
}
@Override
public void turnCrank() {
System.out.println("You turned, but there is no coin");
}
@Override
public void dispense() {
System.out.println("You need to pay first");
}
}
// 已投币状态
public class HasCoinState implements State {
private GumballMachine machine;
public HasCoinState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertCoin() {
System.out.println("You can not insert another coin");
}
@Override
public void ejectCoin() {
machine.setState(machine.getNoCoinState());
System.out.println("Coin returned");
}
@Override
public void turnCrank() {
machine.setState(machine.getSoldState());
System.out.println("You turned ... ");
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
// 已出售状态(正在出货)
public class SoldState implements State {
private GumballMachine machine;
public SoldState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertCoin() {
System.out.println("Please wait, we are already giving you a gumball");
}
@Override
public void ejectCoin() {
System.out.println("Sorry, you already turned the crank");
}
@Override
public void turnCrank() {
System.out.println("Turning twice does not get you another gumball!");
}
@Override
public void dispense() {
if (machine.getGumballNum() > 0) {
machine.setGumballNum(machine.getGumballNum() - 1);
machine.setState(machine.getNoCoinState());
System.out.println("A gumball comes rolling out the slot ... ");
}
if (machine.getGumballNum() <= 0) {
machine.setState(machine.getSoldOutState());
System.out.println("Oops, out of gumballs!");
}
}
}
// 售罄状态
public class SoldOutState implements State {
private GumballMachine machine;
public SoldOutState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertCoin() {
System.out.println("You can not insert a coin, this machine is sold out");
}
@Override
public void ejectCoin() {
System.out.println("Your have not inserted a coin");
}
@Override
public void turnCrank() {
System.out.println("You turned, but there are no gumballs");
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
// 测试类
public class Test {
public static void main(String[] args) {
new Test().test();
}
private void test() {
GumballMachine machine = new GumballMachine(5);
machine.insertCoin();
machine.turnCrank();
}
}
注:
- 当糖果的状态改变的时候,他的所有行为都已经改变
参考文章
1. Head First 设计模式