本文地址: http://blog.csdn.net/caroline_wendy
状态模式(state pattern): 允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类.
建立Context类, 包含多个具体状态(concrete state)类的组合, 根据状态的不同调用具体的方法, state.handle(), 包含set\get方法改变状态.
状态接口(state interface), 包含抽象方法handle(), 具体状态类(concrete state)继承(implement)状态类(state), 实现handle()方法;
具体方法:
1. Context类, 组合多个具体状态类(concrete state), 并提供set\get方法, 调用状态的方法(handle), 改变状态.
/** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State winnerState; State state = soldOutState; int count = 0; /** * */ public GumballMachine(int numberGumballs) { // TODO Auto-generated constructor stub 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.ejectQuater(); } public void turnCrank() { state.turnCrank(); state.dispense(); } void setState(State state) { this.state = state; } void releaseBall() { System.out.println("A gumball comes rolling out the slot..."); if (count != 0) count --; } int getCount() { return count; } void refill(int count) { this.count = count; state = noQuarterState; } public State getState() { return state; } 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 String toString() { StringBuffer result = new StringBuffer(); result.append("\nMighty Gumball, Inc."); result.append("\nJava-enabled Standing Gumball Model #2004\n"); result.append("Inventory: " + count + " gumball"); if (count != 1) { result.append("s"); } result.append("\nMachine is " + state + "\n"); return result.toString(); } }
/** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public interface State { void insertQuarter(); void ejectQuater(); void turnCrank(); void dispense(); }
/** * @time 2014年7月11日 */ package state.pattern; import java.util.Random; /** * @author C.L.Wang * */ public class HasQuarterState implements State { Random randomWinner = new Random(System.currentTimeMillis()); GumballMachine gumballMachine; /** * */ public HasQuarterState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } /* (non-Javadoc) * @see state.pattern.State#insertQuarter() */ @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You can't insert another quarter."); } /* (non-Javadoc) * @see state.pattern.State#ejectQuater() */ @Override public void ejectQuater() { // TODO Auto-generated method stub System.out.println("Quarter returned."); gumballMachine.setState(gumballMachine.getNoQuarterState()); } /* (non-Javadoc) * @see state.pattern.State#turnCrank() */ @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned..."); int winner = randomWinner.nextInt(4); if ((winner == 0) && (gumballMachine.getCount()>1)) { //需要多于1个糖果 gumballMachine.setState(gumballMachine.getWinnerState()); } else { gumballMachine.setState(gumballMachine.getSoldState()); } } /* (non-Javadoc) * @see state.pattern.State#dispense() */ @Override public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed."); } public String toString() { return "waiting for turn of crank"; } } /** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class NoQuarterState implements State { GumballMachine gumballMachine; /** * */ public NoQuarterState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } /* (non-Javadoc) * @see state.pattern.State#insertQuarter() */ @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You inserted a quarter."); gumballMachine.setState(gumballMachine.getHasQuarterState()); } /* (non-Javadoc) * @see state.pattern.State#ejectQuater() */ @Override public void ejectQuater() { // TODO Auto-generated method stub System.out.println("You haven't inserted a quarter."); } /* (non-Javadoc) * @see state.pattern.State#turnCrank() */ @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned, but there's no quarter."); } /* (non-Javadoc) * @see state.pattern.State#dispense() */ @Override public void dispense() { // TODO Auto-generated method stub System.out.println("You need to pay first."); } public String toString() { return "waiting for quater"; } } /** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class SoldOutState implements State { GumballMachine gumballMachine; /** * */ public SoldOutState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } /* (non-Javadoc) * @see state.pattern.State#insertQuarter() */ @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You can't insert a quarter, the machine is sold out."); } /* (non-Javadoc) * @see state.pattern.State#ejectQuater() */ @Override public void ejectQuater() { // TODO Auto-generated method stub System.out.println("You can't eject, you haven't inserted a quarter yet"); } /* (non-Javadoc) * @see state.pattern.State#turnCrank() */ @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned, but there are no gambulls."); } /* (non-Javadoc) * @see state.pattern.State#dispense() */ @Override public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed."); } public String toString() { return "sold out"; } } /** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class SoldState implements State { GumballMachine gumballMachine; /** * */ public SoldState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } /* (non-Javadoc) * @see state.pattern.State#insertQuarter() */ @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("Please wait, we're already giving you a gumball."); } /* (non-Javadoc) * @see state.pattern.State#ejectQuater() */ @Override public void ejectQuater() { // TODO Auto-generated method stub System.out.println("Sorry, you already turned the crank."); } /* (non-Javadoc) * @see state.pattern.State#turnCrank() */ @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("Turning twice doesn't give you another gumball."); } /* (non-Javadoc) * @see state.pattern.State#dispense() */ @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()); } } public String toString() { return "dispensing a gumball"; } } /** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class WinnerState implements State { GumballMachine gumballMachine; /** * */ public WinnerState(GumballMachine gumballMachine) { // TODO Auto-generated constructor stub this.gumballMachine = gumballMachine; } /* (non-Javadoc) * @see state.pattern.State#insertQuarter() */ @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("Please wait, we're already giving you a Gumball"); } /* (non-Javadoc) * @see state.pattern.State#ejectQuater() */ @Override public void ejectQuater() { // TODO Auto-generated method stub System.out.println("Please wait, we're already giving you a Gumball"); } /* (non-Javadoc) * @see state.pattern.State#turnCrank() */ @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("Turning again doesn't give you another gumball!"); } /* (non-Javadoc) * @see state.pattern.State#dispense() */ @Override public void dispense() { // TODO Auto-generated method stub 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()); } } } public String toString() { return "despensing two gumballs for your quarter, because YOU'RE A WINNER!"; } }
/** * @time 2014年7月11日 */ package state.pattern; /** * @author C.L.Wang * */ public class GumballMachineTestDrive { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub GumballMachine gumballMachine = new GumballMachine(5); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); } }
Mighty, Gumball, Inc. Java-enabled Standing Gumball Model #2004 Inventory: 5 gumballs Machine is waiting for quater You inserted a quarter. You turned... A gumball comes rolling out the slot... Mighty Gumball, Inc. Java-enabled Standing Gumball Model #2004 Inventory: 4 gumballs Machine is waiting for quater You inserted a quarter. You turned... YOU'RE A WINNER! you get two gumballs for your quarter. A gumball comes rolling out the slot... A gumball comes rolling out the slot... You inserted a quarter. You turned... YOU'RE A WINNER! you get two gumballs for your quarter. A gumball comes rolling out the slot... A gumball comes rolling out the slot... Oops, out of gumballs! Mighty Gumball, Inc. Java-enabled Standing Gumball Model #2004 Inventory: 0 gumballs Machine is sold out