《HeadFirst设计模式》第十章-状态模式

1.声明设计模式中的设计思想、图片和部分代码参考自《Head First设计模式》,作者Eric Freeman & Elisabeth Freeman & Kathy Siezza & Bert Bates。在这里我只是对这本书进行学习阅读,并向大家分享一些心得体会。2.需求有一家糖果机公司想让我们帮他们做一套软件系统供糖果机使用,并且他们想要达成如下效果...
摘要由CSDN通过智能技术生成

1.声明

设计模式中的设计思想、图片和部分代码参考自《Head First设计模式》作者Eric Freeman & Elisabeth Freeman & Kathy Siezza & Bert Bates。

在这里我只是对这本书进行学习阅读,并向大家分享一些心得体会。

2.需求

有一家糖果机公司想让我们帮他们做一套软件系统供糖果机使用,并且他们想要达成如下效果。

这是一张状态图,每个圆圈表示糖果机的一种状态,每个箭头表示状态的转换过程。例如对于糖果机来说,我们投入25分钱,那么糖果机就由"没有25分钱" ——> "有25分钱"这个状态。

如何由状态图得到真正的代码

第一步:

列出糖果机所有可能的状态。经过分析,可以得到如下四种状态:

没有25分钱
有25分钱
糖果售空
售出糖果

第二步:

为每个状态都赋予一个常量值,并且再定义一个变量,表示当前所处的状态:

//售空
final static int SOLD_OUT = 0;
//无硬币
final static int NO_QUARTER = 1;
//有硬币
final static int HAS_QUARTER = 2;
//售出
final static int SOLD = 3;
 
//糖果机目前所处的状态,初始时默认为无糖果的状态
int state = SOLD_OUT;

第三步:

列出糖果所可能接收到一切动作(指令):

投入25分钱
退回25分钱
转动曲柄
发放糖果

第四步:

创建一个类,这个类的作用就像是一个状态机。对每一个动作( 投入25分钱 ),都需要创建一个对应的方法( insertQuarter() )。

但是糖果机的状态不同,即使接收到相同的动作,那么结果也是不同的。所以在每个方法中,都需要用if分支做判断,根据当前所处的状态,来判断接收到此指令后下个状态是什么。

//投入硬币
public void insertQuarter() {
	if (state == HAS_QUARTER) {
		System.out.println("You can't insert another quarter");
	} else if (state == NO_QUARTER) {
		state = HAS_QUARTER;
		System.out.println("You inserted a quarter");
	} else if (state == SOLD_OUT) {
		System.out.println("You can't insert a quarter, the machine is sold out");
	} else if (state == SOLD) {
        System.out.println("Please wait, we're already giving you a gumball");
	}
}

3.最初的代码设计

糖果机:

//糖果机
public class GumballMachine {
 
	//售空
	final static int SOLD_OUT = 0;
	//无硬币
	final static int NO_QUARTER = 1;
	//有硬币
	final static int HAS_QUARTER = 2;
	//售出
	final static int SOLD = 3;
 
	//糖果机目前所处的状态
	int state = SOLD_OUT;
	//记录糖果机中当前的糖果数量
	int count = 0;
  
	public GumballMachine(int count) {
		this.count = count;
		if (count > 0) {
			state = NO_QUARTER;
		}
	}
  
	//----------------------四种动作----------------------
	//投入硬币
	public void insertQuarter() {
		if (state == HAS_QUARTER) {
			System.out.println("You can't insert another quarter");
		} else if (state == NO_QUARTER) {
			state = HAS_QUARTER;
			System.out.println("You inserted a quarter");
		} else if (state == SOLD_OUT) {
			System.out.println("You can't insert a quarter, the machine is sold out");
		} else if (state == SOLD) {
        	System.out.println("Please wait, we're already giving you a gumball");
		}
	}

	//退回硬币
	public void ejectQuarter() {
		if (state == HAS_QUARTER) {
			System.out.println("Quarter returned");
			state = NO_QUARTER;
		} else if (state == NO_QUARTER) {
			System.out.println("You haven't inserted a quarter");
		} else if (state == SOLD) {
			System.out.println("Sorry, you already turned the crank");
		} else if (state == SOLD_OUT) {
        	System.out.println("You can't eject, you haven't inserted a quarter yet");
		}
	}
 
	//转动曲柄
	public void turnCrank() {
		if (state == SOLD) {
			System.out.println("Turning twice doesn't get you another gumball!");
		} else if (state == NO_QUARTER) {
			System.out.println("You turned but there's no quarter");
		} else if (state == SOLD_OUT) {
			System.out.println("You turned, but there are no gumballs");
		} else if (state == HAS_QUARTER) {
			System.out.println("You turned...");
			state = SOLD;
			dispense();
		}
	}
 
	//发放糖果
	private void dispense() {
		if (state == SOLD) {
			System.out.println("A gumball comes rolling out the slot");
			count = count - 1;
			if (count == 0) {
				System.out.println("Oops, out of gumballs!");
				state = SOLD_OUT;
			} else {
				state = NO_QUARTER;
			}
		} else if (state == NO_QUARTER) {
			System.out.println("You need to pay first");
		} else if (state == SOLD_OUT) {
			System.out.println("No gumball dispensed");
		} else if (state == HAS_QUARTER) {
			System.out.println("No gumball dispensed");
		}
	}
 
	//----------------------其他方法----------------------
	//充值
	public void refill(int numGumBalls) {
		this.count = numGumBalls;
		state = NO_QUARTER;
	}

	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("\nMighty Gumball, Inc.");
		result.append("\nJava-enabled Standing Gumball Model #2004\n");
		result.append("Inventory: " + count + " gumball");
		if (count != 1) {
			result.append("s");
		}
		result.append("\nMachine is ");
		if (state == SOLD_OUT) {
			result.append("sold out");
		} else if (state == NO_QUARTER) {
			result.append("waiting for quarter");
		} else if (state == HAS_QUARTER) {
			result.append("waiting for turn of crank");
		} else if (state == SOLD) {
			result.append("delivering a gumball");
		}
		result.append("\n");
		return result.toString();
	}
}

测试方法:


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琴瘦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值