设计模式之状态模式浅析

   
/**
 * 
 * 状态模式:
 *   允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类
 *   
 * 封装基于状态的行为,并将行为委托到当前状态 
 * 通过把状态封装进一个类,把以后要做的事情局部化了
 * 
 * 策略模式和状态模式有相同的类图,但是彼此的意图不同
 * 
 * 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();
	
}


没有5块钱状态
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]



   状态模式:封装基于状态的行为,并将行为委托给当前状态


posted on 2014-12-18 22:03  liangxinzhi  阅读(130)  评论(0编辑  收藏  举报