デザインモード-ステータスモード(state pattern)詳細


状態モード(state pattern)詳細
この記事のアドレス: http://blog.csdn.net/caroline_wendy
ステータスモード:オブジェクトが内部の状態を変える時にその行動を変えることができます.オブジェクトはそのクラスを修正したように見えます.
Contectクラスを創立して、複数の具体的な状態(concrete state)種類の組合せを含んで、状態によって具体的な方法を呼び出して、state.handle()、 set\getメソッドを含めて状態を変更します.
状態インターフェース(state interface)は、抽象的な方法handle()を含み、具体的な状態類(concrete state)は、(implement)状態類(state)を継承し、handle()方法を実現する.
具体的な方法:
1.Context類は、複数の具体的な状態類を組み合わせて、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("
Mighty Gumball, Inc."); result.append("
Java-enabled Standing Gumball Model #2004
"); result.append("Inventory: " + count + " gumball"); if (count != 1) { result.append("s"); } result.append("
Machine is " + state + "
"); return result.toString(); } }
2.状態インターフェース(state interface)は、抽象的な方法を含む.
/**
 * @time 2014 7 11 
 */
package state.pattern;

/**
 * @author C.L.Wang
 *
 */
public interface State {
	void insertQuarter();
	void ejectQuater();
	void turnCrank();
	void dispense();
}
3.具体的な状態類(concrete state)を継承し、抽象的な方法を実現する.
/**
 * @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!";
	}
}
4.試験類.
/**
 * @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);
	}

}
5.出力.当選2回.
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