针对问题:有时候一个方法可能有很多if..else来判断状态后再执行相关操作,当很多方法都重复的出现这样的if..else判断时,就可以考虑用状态模式了。
状态模式的结构图和策略模式一样,事实上状态模式和策略很相似,不同的是状态模式除了委托状态外,状态实体自身持有主实体对象的引用,在状态实体内部可以动态的改变主实体的状态。
状态模式结构图:
状态模式实现代码:
/** * 状态接口 * @author bruce * */ public interface State { public void insertQuarter(); public void ejectQuarter(); public void turnCrank(); public void dispense(); } /** * 有钱状态 * @author bruce * */ public class HasQuarterState implements State{ GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed"); } public void ejectQuarter() { // TODO Auto-generated method stub System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You can't insert another quarter"); } public void turnCrank() { // TODO Auto-generated method stub System.out.println("You returned..."); gumballMachine.setState(gumballMachine.getSoldState()); } } /** * 没钱状态 * @author bruce * */ public class NoQuarterState implements State{ private GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } public void dispense() { // TODO Auto-generated method stub System.out.println("You need to pay first"); } public void ejectQuarter() { // TODO Auto-generated method stub System.out.println("You haven't inserted a quarter"); } public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned,but there's no quarter"); } } /** * 售出状态 * @author bruce * */ public class SoldState implements State{ private GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } 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 void ejectQuarter() { // TODO Auto-generated method stub System.out.println("Sorry, you already turned the crank"); } public void insertQuarter() { // TODO Auto-generated method stub System.out.println("Please wait, we're already giving you a gumball"); } public void turnCrank() { // TODO Auto-generated method stub System.out.println("Turning twice doesn't get you another gumball!"); } } /** * 卖完状态 * @author bruce * */ public class SoldOutState implements State{ @SuppressWarnings("unused") private GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed"); } public void ejectQuarter() { // TODO Auto-generated method stub System.out.println("You can't eject, you haven't inserted a quarter yet"); } public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You can't insert a quarter,the machine is sold out"); } public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned, but there are no gumballs"); } } /** * 糖果机 * @author bruce * */ public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state=soldOutState; int count=0; public GumballMachine(int numberGumballs){ soldOutState=new SoldOutState(this); noQuarterState=new NoQuarterState(this); hasQuarterState=new HasQuarterState(this); soldState=new SoldState(this); this.count=numberGumballs; if(numberGumballs>0){ state=noQuarterState; } } public void insertQuarter(){ state.insertQuarter(); } public void ejectQuarter(){ state.ejectQuarter(); } 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=count-1; } } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public State getState() { return state; } public int getCount() { return count; } } /** * 测试 * @author bruce * */ public class Client { public static void main(String[] args) { GumballMachine gumballMachine=new GumballMachine(5); System.out.println("-------------"); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println("-------------"); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println("-------------"); /** * output: * ------------- You inserted a quarter You returned... A gumball comes rolling out the slot... ------------- You inserted a quarter You returned... A gumball comes rolling out the slot... You inserted a quarter You returned... A gumball comes rolling out the slot... ------------- */ } }