/** * * 状态模式: * 允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类 * * 封装基于状态的行为,并将行为委托到当前状态 * 通过把状态封装进一个类,把以后要做的事情局部化了 * * 策略模式和状态模式有相同的类图,但是彼此的意图不同 * * State接口定义了一个所有具体状态的共同接口 * Context是一个类,他可以拥有一些内部状态 糖果机就是Context * * 示例 * 糖果机模型 * 5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态 、糖果售罄状态 * 4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果 * * * @author Administrator * */
状态接口 封装行为
package com.undergrowth.state; /** * * 状态模式: * 允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类 * * 封装基于状态的行为,并将行为委托到当前状态 * 通过把状态封装进一个类,把以后要做的事情局部化了 * * 策略模式和状态模式有相同的类图,但是彼此的意图不同 * * State接口定义了一个所有具体状态的共同接口 * Context是一个类,他可以拥有一些内部状态 糖果机就是Context * * 示例 * 糖果机模型 * 5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态 、糖果售罄状态 * 4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果 * * * @author Administrator * */ public interface State { public void insertCoins(); public void coinsHopper(); public void pressSold(); public void soldCandy(); }
package com.undergrowth.state; /** * 没有5块钱的状态 * @author Administrator * */ public class NoMoneyState implements State { GumballMachine gumballMachine; public NoMoneyState(GumballMachine gumballMachine) { super(); this.gumballMachine = gumballMachine; } @Override public void insertCoins() { // TODO Auto-generated method stub System.out.println("你投了5块钱"); gumballMachine.setState(gumballMachine.getHasMoneyState()); } @Override public void coinsHopper() { // TODO Auto-generated method stub System.out.println("你没有投钱,甭想退钱"); } @Override public void pressSold() { // TODO Auto-generated method stub System.out.println("你没有投钱,甭想买糖果"); } @Override public void soldCandy() { // TODO Auto-generated method stub System.out.println("你没有投钱,甭想买糖果"); } }
有5块钱状态
package com.undergrowth.state; import java.util.Random; public class HasMoneyState implements State { GumballMachine gumballMachine; // 记录是够进入玩家模式 Random randomWinner = new Random(System.currentTimeMillis()); public HasMoneyState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } @Override public void insertCoins() { // TODO Auto-generated method stub System.out.println("已经投过币了,不要在投币了"); } @Override public void coinsHopper() { // TODO Auto-generated method stub System.out.println("退币成功"); gumballMachine.setState(gumballMachine.getNoMoneyState()); } @Override public void pressSold() { // TODO Auto-generated method stub System.out.println("你按下售出糖果按钮,即将售出糖果"); int winner = randomWinner.nextInt(10); //十分之一机会 进入赢家模式 if (winner == 0 && gumballMachine.getCount() > 1) { gumballMachine.setState(gumballMachine.getWinnerState()); } else { gumballMachine.setState(gumballMachine.getSoldState()); } } @Override public void soldCandy() { // TODO Auto-generated method stub System.out.println("你没有操作,甭想售出糖果"); } }
售出糖果状态
package com.undergrowth.state; public class SoldState implements State { GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine=gumballMachine; } @Override public void insertCoins() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要投币"); } @Override public void coinsHopper() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要退币"); } @Override public void pressSold() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要再按下售出按钮了"); } @Override public void soldCandy() { // TODO Auto-generated method stub gumballMachine.releaseCandy(); if(gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoMoneyState()); }else { System.out.println("没有糖果了,进入糖果售罄状态"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } }
赢家模式状态
package com.undergrowth.state; public class WinnerState implements State { GumballMachine gumballMachine; public WinnerState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine=gumballMachine; } @Override public void insertCoins() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要投币"); } @Override public void coinsHopper() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要退币"); } @Override public void pressSold() { // TODO Auto-generated method stub System.out.println("正在售出糖果,不要再按下售出按钮了"); } @Override public void soldCandy() { // TODO Auto-generated method stub System.out.println("你进入了赢家模式,会获得两个糖果"); gumballMachine.releaseCandy(); if(gumballMachine.getCount()==0){ System.out.println("没有糖果了,进入糖果售罄状态"); gumballMachine.setState(gumballMachine.getSoldOutState()); }else { gumballMachine.releaseCandy(); if(gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoMoneyState()); }else { System.out.println("没有糖果了,进入糖果售罄状态"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } } }
糖果售完状态
package com.undergrowth.state; public class SoldOutState implements State { GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine=gumballMachine; } @Override public void insertCoins() { // TODO Auto-generated method stub System.out.println("没有糖果了,不要投币"); } @Override public void coinsHopper() { // TODO Auto-generated method stub System.out.println("没有糖果了,不要退币"); } @Override public void pressSold() { // TODO Auto-generated method stub System.out.println("没有糖果了,不要按下售出按钮"); } @Override public void soldCandy() { // TODO Auto-generated method stub System.out.println("没有糖果了"); } }
糖果机 拥有一系列的状态 同时拥有当前状态
package com.undergrowth.state; /** * 糖果机器 * * @author Administrator * */ public class GumballMachine { //状态切换在这5个状态之间 State noMoneyState; State hasMoneyState; State soldState; State soldOutState; State winnerState; // 当前状态 State state; //糖果剩余数 int count; public GumballMachine(int numCandy) { noMoneyState = new NoMoneyState(this); hasMoneyState = new HasMoneyState(this); winnerState = new WinnerState(this); soldState = new SoldState(this); soldOutState = new SoldOutState(this); this.count = numCandy; if (numCandy > 0) { state = noMoneyState; } } public void insertCoins(){ state.insertCoins(); } public void coinsHopper(){ state.coinsHopper(); } public void pressSold(){ state.pressSold(); state.soldCandy(); } void releaseCandy(){ if(count!=0){ System.out.println("你获得一个糖果"); count=count-1; } } public State getNoMoneyState() { return noMoneyState; } public State getHasMoneyState() { return hasMoneyState; } public State getSoldState() { return soldState; } public State getSoldOutState() { return soldOutState; } public State getWinnerState() { return winnerState; } public State getState() { return state; } public int getCount() { return count; } public void setState(State state) { this.state = state; } @Override public String toString() { return "GumballMachine [state=" + state + ", count=" + count + "]"; } }
测试
package com.undergrowth.state.test; import static org.junit.Assert.*; import org.junit.Test; import com.undergrowth.state.GumballMachine; public class GumballMachineTest { @Test public void test() { GumballMachine gumball=new GumballMachine(10); System.out.println(gumball); gumball.insertCoins(); gumball.pressSold(); System.out.println(gumball); gumball.insertCoins(); gumball.pressSold(); System.out.println(gumball); gumball.coinsHopper(); gumball.insertCoins(); System.out.println(gumball); gumball.coinsHopper(); System.out.println(gumball); gumball.insertCoins(); gumball.pressSold(); System.out.println(gumball); gumball.insertCoins(); gumball.pressSold(); gumball.insertCoins(); gumball.pressSold(); gumball.insertCoins(); gumball.pressSold(); System.out.println(gumball); } }
输出结果
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=10] 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你获得一个糖果 GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=9] 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你进入了赢家模式,会获得两个糖果 你获得一个糖果 你获得一个糖果 GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7] 你没有投钱,甭想退钱 你投了5块钱 GumballMachine [state=com.undergrowth.state.HasMoneyState@95ef17, count=7] 退币成功 GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7] 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你获得一个糖果 GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=6] 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你获得一个糖果 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你获得一个糖果 你投了5块钱 你按下售出糖果按钮,即将售出糖果 你获得一个糖果 GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=3]
状态模式:封装基于状态的行为,并将行为委托给当前状态