标签:
1.如何从状态图得到真正的代码:
(1)找出所有状态:没有25分钱,有25分钱,糖果售罄,售出糖果。
(2)创建一个实例变量来持有目前状态,并且定义每个状态的值:
1 final static int SOLD_OUT = 0; 2 final static int NO_QUARTER = 1; 3 final static int HAS_QUARTER = 2; 4 final static int SOLD = 3; 5 6 int state = SOLD_OUT;
(3)找出所有的动作:投入25分钱,退回25分钱,转动曲柄,发放糖果。每一个动作都对应一个方法,而方法内通过条件判断是否可以执行这个动作。
(4)创建一个类,模拟状态机。
1 public class GumballMachine { 2 final static int SOLD_OUT = 0;//售罄 3 final static int NO_QUARTER = 1;//无25分 4 final static int HAS_QUARTER = 2;//有25分 5 final static int SOLD = 3;//售出糖果 6 7 int state = SOLD_OUT; 8 int count = 0;//糖果机内糖果数量 9 10 public GumballMachine(int count) { 11 super(); 12 this.count = count; 13 //如果库存不为0,就会进入“没有25分”,来等待别人投钱。否则就进入“售罄”,无法投钱 14 if(count>0){ 15 state = NO_QUARTER; 16 } 17 } 18 //投钱 19 public void insertQuater(){ 20 if(state == HAS_QUARTER){ 21 System.out.println("已经投过25分"); 22 } 23 else if(state == NO_QUARTER){ 24 System.out.println("你投入了25分"); 25 state = HAS_QUARTER; 26 } 27 else if(state == SOLD_OUT){ 28 System.out.println("已经售罄,无法投钱"); 29 } 30 else if(state == SOLD){ 31 System.out.println("正在出糖果,请等待一会再投钱"); 32 } 33 } 34 //退钱 35 public void ejectQuater(){ 36 if(state == HAS_QUARTER){ 37 System.out.println("退回25分"); 38 state = NO_QUARTER; 39 } 40 else if(state == NO_QUARTER){ 41 System.out.println("您并未投钱"); 42 } 43 else if(state == SOLD_OUT){ 44 System.out.println("您并未投钱"); 45 } 46 else if(state == SOLD){ 47 System.out.println("已经在出糖果,无法退钱"); 48 } 49 } 50 //转动手柄 51 public void turnCrank(){ 52 if(state == HAS_QUARTER){ 53 System.out.println("您转动了手柄"); 54 state = SOLD; 55 dispense(); 56 } 57 else if(state == NO_QUARTER){ 58 System.out.println("请先投钱再转动手柄"); 59 } 60 else if(state == SOLD_OUT){ 61 System.out.println("您并未投钱"); 62 } 63 else if(state == SOLD){ 64 System.out.println("已经给您糖果了,哼,别想骗我"); 65 } 66 } 67 //发放糖果 68 private void dispense() { 69 if(state == HAS_QUARTER){ 70 System.out.println("no gumball dispense"); 71 } 72 else if(state == NO_QUARTER){ 73 System.out.println("请先投钱"); 74 } 75 else if(state == SOLD_OUT){ 76 System.out.println("no gumball dispense"); 77 } 78 else if(state == SOLD){ 79 count = count - 1; 80 if(count ==0){ 81 System.out.println("最后 一颗糖果!"); 82 state = SOLD_OUT; 83 }else{ 84 System.out.println("给您糖果!"); 85 state = NO_QUARTER; 86 } 87 } 88 } 89 }
2.万能糖果机要添加一种游戏:当个赢家!十个人中有1个人可以得到赠送的一颗糖果(也就是说,当曲柄转动时,有10%的机率掉下来的是两颗糖果)。
问题来了:照刚刚的写法,我们首先要添加一个赢家状态,然后再每一个方法中,加入一个新的条件判断来处理“赢家”状态,尤其是turnCrank,因为你必须坚持目前是否"赢家",然后再决定是切换到赢家状态还是售出糖果状态。
解决办法:局部化每个状态的行为,将每个状态的行为都放在各自的类中,那么每个状态都只需要实现自己的动作。
(1)定义一个state接口,在这个接口里,糖果机的每个动作都有一个对应的方法。
(2)为每个状态实现状态类,这些类负责对应状态下机器的行为。
(3)摆脱条件判断代码,将动作委托到状态类。
1 public interface State { 2 public void insertQuater(); 3 public void ejectQuater(); 4 public void turnCrank(); 5 public void dispense(); 6 }
1 public class GumballMachine { 2 State soldOutState; 3 State soldState; 4 State hasQuarterState; 5 State noQuarterState; 6 7 State state = soldOutState; 8 int count = 0; 9 10 public GumballMachine(int count) { 11 super(); 12 soldOutState = new SoldOutState(this); 13 soldState = new SoldState(this); 14 hasQuarterState = new HasQuarterState(this); 15 noQuarterState = new NoQuarterState(this); 16 this.count = count; 17 //如果库存不为0,就会进入“没有25分”,来等待别人投钱。否则就进入“售罄”,无法投钱 18 if(count>0){ 19 state = noQuarterState; 20 } 21 } 22 //投钱 23 public void insertQuater(){ 24 state.insertQuater(); 25 } 26 //退钱 27 public void ejectQuater(){ 28 state.ejectQuater(); 29 } 30 //转动手柄 31 public void turnCrank(){ 32 state.turnCrank(); 33 state.dispense(); 34 } 35 public void setState(State state) { 36 this.state = state; 37 } 38 39 void releasBall(){ 40 System.out.println("糖果正在滚出来的路上"); 41 if(count!=0){ 42 count = count-1; 43 } 44 } 45 public State getSoldOutState() { 46 return soldOutState; 47 } 48 public State getSoldState() { 49 return soldState; 50 } 51 public State getHasQuarterState() { 52 return hasQuarterState; 53 } 54 public State getNoQuarterState() { 55 return noQuarterState; 56 } 57 }
1 public class SoldState implements State { 2 3 GumballMachine gumballMachine; 4 5 public SoldState(GumballMachine gumballMachine) { 6 super(); 7 this.gumballMachine = gumballMachine; 8 } 9 10 public void dispense() { 11 gumballMachine.releasBall(); 12 if(gumballMachine.getCount()>0){ 13 gumballMachine.setState(gumballMachine.getNoQuarterState()); 14 }else{ 15 System.out.println("卖完了"); 16 gumballMachine.setState(gumballMachine.getSoldOutState()); 17 } 18 } 19 20 public void ejectQuater() { 21 System.out.println("准备发糖,无法退钱"); 22 } 23 24 public void insertQuater() { 25 System.out.println("请等糖出完"); 26 } 27 28 public void turnCrank() { 29 System.out.println("已经在出糖,不用转动手柄了"); 30 } 31 32 }
3.别忘了,我们游戏还没完成呢:
待续。
标签:
原文地址:http://www.cnblogs.com/liyuhui21310122/p/4471490.html