设计模式 状态模式 以自动售货机为例(四)

2014-11-23 20:19:57 · 作者: · 浏览: 32
} else { System.out.println("商品已经售罄"); machine.setState(machine.getSoldOutState()); } } }

package com.zhy.pattern.status.b;

/**
 * 中奖的状态,该状态下不会有任何用户的操作
 * 
 * @author zhy
 * 
 */
public class WinnerState implements State
{

	private VendingMachine machine;

	public WinnerState(VendingMachine machine)
	{
		this.machine = machine;
	}

	@Override
	public void insertMoney()
	{
		throw new IllegalStateException("非法状态");
	}

	@Override
	public void backMoney()
	{
		throw new IllegalStateException("非法状态");
	}

	@Override
	public void turnCrank()
	{
		throw new IllegalStateException("非法状态");
	}

	@Override
	public void dispense()
	{
		System.out.println("你中奖了,恭喜你,将得到2件商品");
		machine.dispense();

		if (machine.getCount() == 0)
		{
			System.out.println("商品已经售罄");
			machine.setState(machine.getSoldOutState());
		} else
		{
			machine.dispense();
			if (machine.getCount() > 0)
			{
				machine.setState(machine.getNoMoneyState());
			} else
			{
				System.out.println("商品已经售罄");
				machine.setState(machine.getSoldOutState());
			}
			
		}

	}

}


最后是自动售货机的代码:

package com.zhy.pattern.status.b;

/**
 * 自动售货机
 * 
 * @author zhy
 * 
 */
public class VendingMachine
{
	private State noMoneyState;
	private State hasMoneyState;
	private State soldState;
	private State soldOutState;
	private State winnerState ; 

	private int count = 0;
	private State currentState = noMoneyState;

	public VendingMachine(int count)
	{
		noMoneyState = new NoMoneyState(this);
		hasMoneyState = new HasMoneyState(this);
		soldState = new SoldState(this);
		soldOutState = new SoldOutState(this);
		winnerState = new WinnerState(this);

		if (count > 0)
		{
			this.count = count;
			currentState = noMoneyState;
		}
	}

	public void insertMoney()
	{
		currentState.insertMoney();
	}

	public void backMoney()
	{
		currentState.backMoney();
	}

	public void turnCrank()
	{
		currentState.turnCrank();
		if (currentState == soldState || currentState == winnerState)
			currentState.dispense();
	}

	public void dispense()
	{
		System.out.println("发出一件商品...");
		if (count != 0)
		{
			count -= 1;
		}
	}

	public void setState(State state)
	{
		this.currentState = state;
	}

	//getter setter omitted ...

}

可以看到,我们现在把每个状态对应于动作的行为局部化到了状态自己的类中实现,不仅增加了扩展性而且使代码的 阅读性大幅度的提高。以后再添加状态,只需要针对新添加的状态的实现类,并在自动售货机中添加此状态即可。

下面进行一些测试:

package com.zhy.pattern.status.b;

public class Test
{
	public static void main(String[] args)
	{
		VendingMachine machine = new VendingMachine(10);
		machine.insertMoney();
		machine.backMoney();

		System.out.println("----我要中奖----");

		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();
		machine.insertMoney();
		machine.turnCrank();

		System.out.println("-------压力测试------");

		machine.insertMoney();
		machine.backMoney();
		machine.backMoney();
		machine.turnCrank();// 无效操作
		machine.turnCrank();// 无效操作
		machine.backMoney();

	}
}

输出结果:

投币成功
退币成功
----我要中奖----
投币成