先看定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。定义又开始模糊了,理一下,当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。
下面使用个例子来说明状态模式的用法,现在有个自动售货机的代码需要我们来写,状态图如下:
分析一个这个状态图:
a、包含4个状态(我们使用4个int型常量来表示)
b、包含3个暴露在外的方法(投币、退币、转动手柄)
c、我们需要处理每个状态下,用户都可以触发这三个动作。
下面我们根据分析的结果,写出代码:
package com.zhy.pattern.status;
/**
* 自动售货机
*
* @author zhy
*
*/
public class VendingMachine {
/**
* 已投币
*/
private final static int HAS_MONEY = 0;
/**
* 未投币
*/
private final static int NO_MONEY = 1;
/**
* 售出商品
*/
private final static int SOLD = 2;
/**
* 商品售罄
*/
private final static int SOLD_OUT = 3;
private int currentStatus = NO_MONEY;
/**
* 商品数量
*/
private int count = 0;
public VendingMachine(int count) {
this.count = count;
if (count > 0) {
currentStatus = NO_MONEY;
}
}
/**
* 投入硬币,任何状态用户都可能投币
*/
public void insertMoney() {
switch (currentStatus) {
case NO_MONEY:
currentStatus = HAS_MONEY;
System.out.println("成功投入硬币");
break;
case HAS_MONEY:
System.out.println("已经有硬币,无需投币");
break;
case SOLD:
System.out.println("请稍等...");
break;
case SOLD_OUT:
System.out.println("商品已经售罄,请勿投币");
break;
}
}
/**
* 退币,任何状态用户都可能退币
*/
public void backMoney() {
switch (currentStatus) {
case NO_MONEY:
System.out.println("您未投入硬币");
break;
case HAS_MONEY:
currentStatus = NO_MONEY;
System.out.println("退币成功");
break;
case SOLD:
System.out.println("您已经买了糖果...");
break;
case SOLD_OUT:
System.out.println("您未投币...");
break;
}
}
/**
* 转动手柄购买,任何状态用户都可能转动手柄
*/
public void turnCrank() {
switch (currentStatus) {
case NO_MONEY:
System.out.println("请先投入硬币");
break;
case HAS_MONEY:
System.out.println("正在出商品....");
currentStatus = SOLD;
dispense();
break;
case SOLD:
System.out.println("连续转动也没用...");
break;
case SOLD_OUT:
System.out.println("商品已经售罄");
break;
}
}
/**
* 发放商品
*/
private void dispense() {
switch (currentStatus) {
case NO_MONEY:
case HAS_MONEY:
case SOLD_OUT:
throw new IllegalStateException("非法的状态...");
case SOLD:
count--;
System.out.println("发出商品...");
if (count == 0) {
System.out.println("商品售罄");
currentStatus = SOLD_OUT;
} else {
currentStatus = NO_MONEY;
}
break;
}
}
}
针对用户的每个动作,我们考虑了在任何状态下发生,并做了一定处理。下面进行一些测试:
package com.zhy.pattern.status;
public class TestTra {
public static void main(String[] args) {
VendingMachine machine = new VendingMachine(10);
machine.insertMoney();
machine.backMoney();
System.out.println("-----------");
machine.insertMoney();
machine.turnCrank();
System.out.println("----------压力测试-----");
machine.insertMoney();
machine.insertMoney();
machine.turnCrank();
machine.turnCrank();
machine.backMoney();
machine.turnCrank();
}
}
输出结果:
成功投入硬币
退币成功
-----------
成功投入硬币
正在出商品....
发出商品...
----------压力测试-----
成功投入硬币
已经有硬币,无需投币
正在出商品....
发出商品...
请先投入硬币
您未投入硬币
请先投入硬币
————————————————
版权声明:本文为CSDN博主「鸿洋_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lmj623565791/article/details/26350617