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.依 ...
随机推荐
- GitHub 基本操作流程
GitHub是最先进的分布式版本控制工具,下面是我学习中总结的操作流程,仅供参考 ----------------------------------------------------------- ...
- libnet发包例子(tcp udp arp广播)
#include <libnet.h> int main() { libnet_t *handle; /* Libnet句柄 */ int packet_size; /* 构造的数据包大小 ...
- 初试集群虚拟化搭建(二)—— Xen, kvm, OpenStack, VMware ESXi, Citrix XenServer等种种选择
小伙伴们找到了一些主流方案的资料,最终选择了XenServer6.5作为平台搭建. Xen 特点: 功能强大,支持Linux的各种发行版本 通常是在现有Linux操作系统上安装,是一种半虚拟化的安装方 ...
- C#如何获取快捷方式指向的目标文件
前几天,做个小程序时遇到的问题,在百度上搜索了很久,没有发现好的解决方案,在英文网站上立刻搜到办法,看来还是国外的资源要全面一些,只是Google经常访问不正常,没办法啊. “C#如何获取快捷方式指向 ...
- centos架设FTP服务器
1.安装vsftp在这里,我们架设的是虚拟用户,所谓虚拟用户就是没有使用真实的帐户,只是通过某种手段达到映射帐户和设置权限的目的.yum -y install vsftpd在CentOS中,这样就可以 ...
- EditorLineEnds.ttr 受影响的D版本 Delphi 8-2010
http://stackoverflow.com/questions/25295980/delphi-2006-2010-error-cannot-create-file-c-users-admin- ...
- Spark Streaming揭秘 Day28 在集成开发环境中详解Spark Streaming的运行日志内幕
Spark Streaming揭秘 Day28 在集成开发环境中详解Spark Streaming的运行日志内幕 今天会逐行解析一下SparkStreaming运行的日志,运行的是WordCountO ...
- scala知识点(一)
1.drop,dropRight,dropWhile drop: drop(n: Int): List[A] 丢弃前n个元素,返回剩下的元素 dropRight: dropRight(n: Int): ...
- 1048. Find Coins (25)
时间限制 50 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Eva loves to collect coins from a ...
- poj 2774 Long Long Message 后缀数组LCP理解
题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #inclu ...