
如果在我们刚写的代码上直接添加,则需要在每个动作的switch中添加判断条件,且非常容易出错。所以现在我们要考虑重新设计我们的代码,我们考虑把每个状态写状态类,负责实现在对应动作下的行为,然后自动售货机在不能的状态间切换:
下面开始重构,我们现在有5种状态,对应4个动作(投币、退币、转动手柄、发出商品),下面首先定义一个状态的超类型:
package com.zhy.pattern.status.b;
/**
* 状态的接口
* @author zhy
*
*/
public interface State
{
/**
* 放钱
*/
public void insertMoney();
/**
* 退钱
*/
public void backMoney();
/**
* 转动曲柄
*/
public void turnCrank();
/**
* 出商品
*/
public void dispense();
}
然后分别是每个状态的实现:
package com.zhy.pattern.status.b;
/**
* 没钱的状态
* @author zhy
*
*/
public class NoMoneyState implements State
{
private VendingMachine machine;
public NoMoneyState(VendingMachine machine)
{
this.machine = machine;
}
@Override
public void insertMoney()
{
System.out.println("投币成功");
machine.setState(machine.getHasMoneyState());
}
@Override
public void backMoney()
{
System.out.println("您未投币,想退钱?...");
}
@Override
public void turnCrank()
{
System.out.println("您未投币,想拿东西么?...");
}
@Override
public void dispense()
{
throw new IllegalStateException("非法状态!");
}
}
package com.zhy.pattern.status.b;
import java.util.Random;
/**
* 已投入钱的状态
*
* @author zhy
*
*/
public class HasMoneyState implements State
{
private VendingMachine machine;
private Random random = new Random();
public HasMoneyState(VendingMachine machine)
{
this.machine = machine;
}
@Override
public void insertMoney()
{
System.out.println("您已经投过币了,无需再投....");
}
@Override
public void backMoney()
{
System.out.println("退币成功");
machine.setState(machine.getNoMoneyState());
}
@Override
public void turnCrank()
{
System.out.println("你转动了手柄");
int winner = random.nextInt(10);
if (winner == 0 && machine.getCount() > 1)
{
machine.setState(machine.getWinnerState());
} else
{
machine.setState(machine.getSoldState());
}
}
@Override
public void dispense()
{
throw new IllegalStateException("非法状态!");
}
}
package com.zhy.pattern.status.b;
/**
* 售罄的状态
*
* @author zhy
*
*/
public class SoldOutState implements State
{
private VendingMachine machine;
public SoldOutState(VendingMachine machine)
{
this.machine = machine;
}
@Override
public void insertMoney()
{
System.out.println("投币失败,商品已售罄");
}
@Override
public void backMoney()
{
System.out.println("您未投币,想退钱么?...");
}
@Override
public void turnCrank()
{
System.out.println("商品售罄,转动手柄也木有用");
}
@Override
public void dispense()
{
throw new IllegalStateException("非法状态!");
}
}
package com.zhy.pattern.status.b;
/**
* 准备出商品的状态,该状态下,不会有任何用户的操作
*
* @author zhy
*
*/
public class SoldState implements State
{
private VendingMachine machine;
public SoldState(VendingMachine machine)
{
this.machine = machine;
}
@Override
public void insertMoney()
{
System.out.println("正在出货,请勿投币");
}
@Override
public void backMoney()
{
System.out.println("正在出货,没有可退的钱");
}
@Override
public void turnCrank()
{
System.out.println("正在出货,请勿重复转动手柄");
}
@Override
public void dispense()
{
machine.dispense();
if (machine.getCount() > 0)
{
machine.setState(machine.getNoMoneyState());