HeadFirst设计模式之状态模式
一、
1.
2.The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
3.The State Pattern allows an object to have many different behaviors that are based on its internal state.
4.The Context gets its behavior by delegating to the current state object it is composed with.
5.
Strategy Pattern typically configures Context classes with a behavior or algorithm.State Pattern allows a Context to change its behavior as the state of the Context changes.
二、
这种写法若要增加一个状态时,会修改很多
1.
package headfirst.designpatterns.state.gumball; 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) {
//if the inventory isn’t zero, the machine enters state NO_QUARTER,
//meaning it is waiting for someone to insert a quarter,
//otherwise it stays in the SOLD_OUT state.
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();
}
}
2.
package headfirst.designpatterns.state.gumball; public class GumballMachineTestDrive { public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.ejectQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.ejectQuarter(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine);
}
}
三、
1.
It looks like we’ve got a new plan: instead of maintaining our existing code, we’re going to
rework it to encapsulate state objects in their own classes and then delegate to the current
state when an action occurs.
We’re following our design principles here, so we should end up with a design that is easier to
maintain down the road. Here’s how we’re going to do it:
First, we’re going to define a State interface that
contains a method for every action in the Gumball
Machine.
Then we’re going to implement a State class for
every state of the machine. These classes will be
responsible for the behavior of the machine when it
is in the corresponding state.
Finally, we’re going to get rid of all of our conditional
code and instead delegate to the state class to do
the work for us.
2.
3.
4.
5.
6.
四、
1.
package headfirst.designpatterns.state.gumballstatewinner; public interface State { public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense(); public void refill();
}
2.
package headfirst.designpatterns.state.gumballstatewinner; import java.util.Random; public class HasQuarterState implements State {
Random randomWinner = new Random(System.currentTimeMillis());
GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
} public void insertQuarter() {
System.out.println("You can't insert another quarter");
} public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
} public void turnCrank() {
System.out.println("You turned...");
int winner = randomWinner.nextInt(10);
if ((winner == 0) && (gumballMachine.getCount() > 1)) {
gumballMachine.setState(gumballMachine.getWinnerState());
} else {
gumballMachine.setState(gumballMachine.getSoldState());
}
} public void dispense() {
System.out.println("No gumball dispensed");
} public void refill() { } public String toString() {
return "waiting for turn of crank";
}
}
3.
package headfirst.designpatterns.state.gumballstatewinner; public class NoQuarterState implements State {
GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
} public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
} public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
} public void turnCrank() {
System.out.println("You turned, but there's no quarter");
} public void dispense() {
System.out.println("You need to pay first");
} public void refill() { } public String toString() {
return "waiting for quarter";
}
}
4.
package headfirst.designpatterns.state.gumballstatewinner; public class SoldOutState implements State {
GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
} public void insertQuarter() {
System.out.println("You can't insert a quarter, the machine is sold out");
} public void ejectQuarter() {
System.out.println("You can't eject, you haven't inserted a quarter yet");
} public void turnCrank() {
System.out.println("You turned, but there are no gumballs");
} public void dispense() {
System.out.println("No gumball dispensed");
} public void refill() {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} public String toString() {
return "sold out";
}
}
5.
package headfirst.designpatterns.state.gumballstatewinner; public class SoldState implements State {
GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
} public void insertQuarter() {
System.out.println("Please wait, we're already giving you a gumball");
} public void ejectQuarter() {
System.out.println("Sorry, you already turned the crank");
} public void turnCrank() {
System.out.println("Turning twice doesn't get you another gumball!");
} public void dispense() {
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
} public void refill() { } public String toString() {
return "dispensing a gumball";
}
}
6.
package headfirst.designpatterns.state.gumballstatewinner; public class WinnerState implements State {
GumballMachine gumballMachine; public WinnerState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
} public void insertQuarter() {
System.out.println("Please wait, we're already giving you a Gumball");
} public void ejectQuarter() {
System.out.println("Please wait, we're already giving you a Gumball");
} public void turnCrank() {
System.out.println("Turning again doesn't get you another gumball!");
} public void dispense() {
gumballMachine.releaseBall();
if (gumballMachine.getCount() == 0) {
gumballMachine.setState(gumballMachine.getSoldOutState());
} else {
gumballMachine.releaseBall();
System.out.println("YOU'RE A WINNER! You got two gumballs for your quarter");
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
} public void refill() { } public String toString() {
return "despensing two gumballs for your quarter, because YOU'RE A WINNER!";
}
}
7.
package headfirst.designpatterns.state.gumballstatewinner; public class GumballMachine { State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState; State state = soldOutState;
int count = 0; public GumballMachine(int numberGumballs) {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this); this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
} public void insertQuarter() {
state.insertQuarter();
} public void ejectQuarter() {
state.ejectQuarter();
} public void turnCrank() {
state.turnCrank();
state.dispense();
} void setState(State state) {
this.state = state;
} void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count = count - 1;
}
} int getCount() {
return count;
} void refill(int count) {
this.count += count;
System.out.println("The gumball machine was just refilled; it's new count is: " + this.count);
state.refill();
} public State getState() {
return state;
} public State getSoldOutState() {
return soldOutState;
} public State getNoQuarterState() {
return noQuarterState;
} public State getHasQuarterState() {
return hasQuarterState;
} public State getSoldState() {
return soldState;
} public State getWinnerState() {
return winnerState;
} public String toString() {
StringBuffer result = new StringBuffer();
result.append("\nMighty Gumball, Inc.");
result.append("\nJava-enabled Standing Gumball Model #2004");
result.append("\nInventory: " + count + " gumball");
if (count != 1) {
result.append("s");
}
result.append("\n");
result.append("Machine is " + state + "\n");
return result.toString();
}
}
8.
package headfirst.designpatterns.state.gumballstatewinner; public class GumballMachineTestDrive { public static void main(String[] args) {
GumballMachine gumballMachine =
new GumballMachine(10); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank(); System.out.println(gumballMachine);
}
}
HeadFirst设计模式之状态模式的更多相关文章
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- js设计模式——5.状态模式
js设计模式——5.状态模式 代码演示 /*js设计模式——状态模式*/ // 状态(红灯,黄灯,绿灯) class State { constructor(color) { this.color = ...
- 设计模式2——状态模式State
参考链接: 设计模式之状态模式:https://www.cnblogs.com/haoerlv/p/7777789.html 设计模式系列之状态模式:https://www.jianshu.com/p ...
- python设计模式之状态模式
python设计模式之状态模式 面向对象编程着力于在对象交互时改变它们的状态.在很多问题中,有限状态机(通常名为状态机)是一个非常方便的状态转换建模(并在必要时以数学方式形式化)工具.首先,什么是状态 ...
- Head First 设计模式 --10 状态模式
状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类. 用到的设计原则1.封装变化2.多用组合,少用继承3.针对接口编程,不针对实现编程4.松耦合5.对扩展开放,对修改关闭6.依 ...
随机推荐
- (转)持续化集成工具CruiseControl.NET
持续化集成工具CC.NET[ 引言: 团队开发需要 进行集中的项目文件管理与有效的协调,我们采用源代码管理工具协助我们管理,卓有成效.限定重要文件的访问权限.使用悲观锁杜绝成员同时编辑同一份文件. 不 ...
- CSS的继承与优先级
CSS样式继承性 body,div,p{} html文档可以上图的种种节点树的形式表示,css层叠样式表中的各元素也有这种对应关系 <body>是文档中最大的根节点,body中的所有元素都 ...
- linux file命令小记
在linux中,所有东西都是文件:而且他并没有后缀名这一概念.Linux的扩展名没有太大的意义, file.tar.gz file.tgz file.tar.bz2 file.rar file.gz ...
- json-lib-2.4.jar Bug,json字符串中value为"[value]"结构时,解析为数组,不会解析成字符串
使用json-lib.jar 2.4进行json字符串转换为对象时发现一个bug.贴下测试代码: <dependency> <groupId>net.sf.json-lib&l ...
- fedora下python3 安装tkinter和pygame
root 下用 “yum search tkinter”,如下图所示: 然后再根据系统选择安装就好了. tkinter安装完毕. 接下来是安装pygame在fedora的python3上,我的是pyt ...
- 用PHP生成随机数的函数
转自:http://www.jbxue.com/article/5034.html 介绍:在早期的php中生成一个随机字符串时,总是先创建一个字符池,然后用一个循环和mt_rand()或rand()生 ...
- J2EE中文乱码处理
在JAVA WEB开发的过程中,经常会遇到中文乱码的情况,中文乱码主要是在浏览器与服务器交互传递数据的时候发生的.对于这个棘手的问题,我参考(韩顺平老师)视频将处理方法总结与此,供自己以及大家开发的时 ...
- C#向C++编写的DLL传递字符串参数的办法
使用StringBuilder,举例: C++代码中函数定义如下: PVPOWERFORCASTDLL_API int PVPowerForcast(SForcastInfo &_Forcas ...
- EXTJS 4.2 资料 控件textfield中fieldLabel去掉冒号,控件label的长度
代码: labelSeparator: '', // 去掉laebl中的冒号 labelWidth: 10,//控件label的长度
- Objective-C程序结构及语法特点
程序文件分为头文件(.h)和实现文件(.m): 使用#import关键字将所需的头文件导入程序,并且可以避免程序重复引用相同的头文件: @autoreleasepool { … } 自动释放池: 符号 ...