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.

  1 package headfirst.designpatterns.state.gumball;
  2
  3 public class GumballMachine {
  4
  5     final static int SOLD_OUT = 0;
  6     final static int NO_QUARTER = 1;
  7     final static int HAS_QUARTER = 2;
  8     final static int SOLD = 3;
  9
 10     int state = SOLD_OUT;
 11     int count = 0;
 12
 13     public GumballMachine(int count) {
 14         this.count = count;
 15         if (count > 0) {
 16             //if the inventory isn’t zero, the machine enters state NO_QUARTER,
 17             //meaning it is waiting for someone to insert a quarter,
 18             //otherwise it stays in the SOLD_OUT state.
 19             state = NO_QUARTER;
 20         }
 21     }
 22
 23     public void insertQuarter() {
 24         if (state == HAS_QUARTER) {
 25             System.out.println("You can‘t insert another quarter");
 26         } else if (state == NO_QUARTER) {
 27             state = HAS_QUARTER;
 28             System.out.println("You inserted a quarter");
 29         } else if (state == SOLD_OUT) {
 30             System.out.println("You can‘t insert a quarter, the machine is sold out");
 31         } else if (state == SOLD) {
 32             System.out.println("Please wait, we‘re already giving you a gumball");
 33         }
 34     }
 35
 36     public void ejectQuarter() {
 37         if (state == HAS_QUARTER) {
 38             System.out.println("Quarter returned");
 39             state = NO_QUARTER;
 40         } else if (state == NO_QUARTER) {
 41             System.out.println("You haven‘t inserted a quarter");
 42         } else if (state == SOLD) {
 43             System.out.println("Sorry, you already turned the crank");
 44         } else if (state == SOLD_OUT) {
 45             System.out.println("You can‘t eject, you haven‘t inserted a quarter yet");
 46         }
 47     }
 48
 49     public void turnCrank() {
 50         if (state == SOLD) {
 51             System.out.println("Turning twice doesn‘t get you another gumball!");
 52         } else if (state == NO_QUARTER) {
 53             System.out.println("You turned but there‘s no quarter");
 54         } else if (state == SOLD_OUT) {
 55             System.out.println("You turned, but there are no gumballs");
 56         } else if (state == HAS_QUARTER) {
 57             System.out.println("You turned...");
 58             state = SOLD;
 59             dispense();
 60         }
 61     }
 62
 63     private void dispense() {
 64         if (state == SOLD) {
 65             System.out.println("A gumball comes rolling out the slot");
 66             count = count - 1;
 67             if (count == 0) {
 68                 System.out.println("Oops, out of gumballs!");
 69                 state = SOLD_OUT;
 70             } else {
 71                 state = NO_QUARTER;
 72             }
 73         } else if (state == NO_QUARTER) {
 74             System.out.println("You need to pay first");
 75         } else if (state == SOLD_OUT) {
 76             System.out.println("No gumball dispensed");
 77         } else if (state == HAS_QUARTER) {
 78             System.out.println("No gumball dispensed");
 79         }
 80     }
 81
 82     public void refill(int numGumBalls) {
 83         this.count = numGumBalls;
 84         state = NO_QUARTER;
 85     }
 86
 87     public String toString() {
 88         StringBuffer result = new StringBuffer();
 89         result.append("\nMighty Gumball, Inc.");
 90         result.append("\nJava-enabled Standing Gumball Model #2004\n");
 91         result.append("Inventory: " + count + " gumball");
 92         if (count != 1) {
 93             result.append("s");
 94         }
 95         result.append("\nMachine is ");
 96         if (state == SOLD_OUT) {
 97             result.append("sold out");
 98         } else if (state == NO_QUARTER) {
 99             result.append("waiting for quarter");
100         } else if (state == HAS_QUARTER) {
101             result.append("waiting for turn of crank");
102         } else if (state == SOLD) {
103             result.append("delivering a gumball");
104         }
105         result.append("\n");
106         return result.toString();
107     }
108 }

2.

 1 package headfirst.designpatterns.state.gumball;
 2
 3 public class GumballMachineTestDrive {
 4
 5     public static void main(String[] args) {
 6         GumballMachine gumballMachine = new GumballMachine(5);
 7
 8         System.out.println(gumballMachine);
 9
10         gumballMachine.insertQuarter();
11         gumballMachine.turnCrank();
12
13         System.out.println(gumballMachine);
14
15         gumballMachine.insertQuarter();
16         gumballMachine.ejectQuarter();
17         gumballMachine.turnCrank();
18
19         System.out.println(gumballMachine);
20
21         gumballMachine.insertQuarter();
22         gumballMachine.turnCrank();
23         gumballMachine.insertQuarter();
24         gumballMachine.turnCrank();
25         gumballMachine.ejectQuarter();
26
27         System.out.println(gumballMachine);
28
29         gumballMachine.insertQuarter();
30         gumballMachine.insertQuarter();
31         gumballMachine.turnCrank();
32         gumballMachine.insertQuarter();
33         gumballMachine.turnCrank();
34         gumballMachine.insertQuarter();
35         gumballMachine.turnCrank();
36
37         System.out.println(gumballMachine);
38     }
39 }

三、

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.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public interface State {
 4
 5     public void insertQuarter();
 6     public void ejectQuarter();
 7     public void turnCrank();
 8     public void dispense();
 9
10     public void refill();
11 }

2.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 import java.util.Random;
 4
 5 public class HasQuarterState implements State {
 6     Random randomWinner = new Random(System.currentTimeMillis());
 7     GumballMachine gumballMachine;
 8
 9     public HasQuarterState(GumballMachine gumballMachine) {
10         this.gumballMachine = gumballMachine;
11     }
12
13     public void insertQuarter() {
14         System.out.println("You can‘t insert another quarter");
15     }
16
17     public void ejectQuarter() {
18         System.out.println("Quarter returned");
19         gumballMachine.setState(gumballMachine.getNoQuarterState());
20     }
21
22     public void turnCrank() {
23         System.out.println("You turned...");
24         int winner = randomWinner.nextInt(10);
25         if ((winner == 0) && (gumballMachine.getCount() > 1)) {
26             gumballMachine.setState(gumballMachine.getWinnerState());
27         } else {
28             gumballMachine.setState(gumballMachine.getSoldState());
29         }
30     }
31
32     public void dispense() {
33         System.out.println("No gumball dispensed");
34     }
35
36     public void refill() { }
37
38     public String toString() {
39         return "waiting for turn of crank";
40     }
41 }

3.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class NoQuarterState implements State {
 4     GumballMachine gumballMachine;
 5
 6     public NoQuarterState(GumballMachine gumballMachine) {
 7         this.gumballMachine = gumballMachine;
 8     }
 9
10     public void insertQuarter() {
11         System.out.println("You inserted a quarter");
12         gumballMachine.setState(gumballMachine.getHasQuarterState());
13     }
14
15     public void ejectQuarter() {
16         System.out.println("You haven‘t inserted a quarter");
17     }
18
19     public void turnCrank() {
20         System.out.println("You turned, but there‘s no quarter");
21      }
22
23     public void dispense() {
24         System.out.println("You need to pay first");
25     }
26
27     public void refill() { }
28
29     public String toString() {
30         return "waiting for quarter";
31     }
32 }

4.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class SoldOutState implements State {
 4     GumballMachine gumballMachine;
 5
 6     public SoldOutState(GumballMachine gumballMachine) {
 7         this.gumballMachine = gumballMachine;
 8     }
 9
10     public void insertQuarter() {
11         System.out.println("You can‘t insert a quarter, the machine is sold out");
12     }
13
14     public void ejectQuarter() {
15         System.out.println("You can‘t eject, you haven‘t inserted a quarter yet");
16     }
17
18     public void turnCrank() {
19         System.out.println("You turned, but there are no gumballs");
20     }
21
22     public void dispense() {
23         System.out.println("No gumball dispensed");
24     }
25
26     public void refill() {
27         gumballMachine.setState(gumballMachine.getNoQuarterState());
28     }
29
30     public String toString() {
31         return "sold out";
32     }
33 }

5.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class SoldState implements State {
 4     GumballMachine gumballMachine;
 5
 6     public SoldState(GumballMachine gumballMachine) {
 7         this.gumballMachine = gumballMachine;
 8     }
 9
10     public void insertQuarter() {
11         System.out.println("Please wait, we‘re already giving you a gumball");
12     }
13
14     public void ejectQuarter() {
15         System.out.println("Sorry, you already turned the crank");
16     }
17
18     public void turnCrank() {
19         System.out.println("Turning twice doesn‘t get you another gumball!");
20     }
21
22     public void dispense() {
23         gumballMachine.releaseBall();
24         if (gumballMachine.getCount() > 0) {
25             gumballMachine.setState(gumballMachine.getNoQuarterState());
26         } else {
27             System.out.println("Oops, out of gumballs!");
28             gumballMachine.setState(gumballMachine.getSoldOutState());
29         }
30     }
31
32     public void refill() { }
33
34     public String toString() {
35         return "dispensing a gumball";
36     }
37 }

6.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class WinnerState implements State {
 4     GumballMachine gumballMachine;
 5
 6     public WinnerState(GumballMachine gumballMachine) {
 7         this.gumballMachine = gumballMachine;
 8     }
 9
10     public void insertQuarter() {
11         System.out.println("Please wait, we‘re already giving you a Gumball");
12     }
13
14     public void ejectQuarter() {
15         System.out.println("Please wait, we‘re already giving you a Gumball");
16     }
17
18     public void turnCrank() {
19         System.out.println("Turning again doesn‘t get you another gumball!");
20     }
21
22     public void dispense() {
23         gumballMachine.releaseBall();
24         if (gumballMachine.getCount() == 0) {
25             gumballMachine.setState(gumballMachine.getSoldOutState());
26         } else {
27             gumballMachine.releaseBall();
28             System.out.println("YOU‘RE A WINNER! You got two gumballs for your quarter");
29             if (gumballMachine.getCount() > 0) {
30                 gumballMachine.setState(gumballMachine.getNoQuarterState());
31             } else {
32                 System.out.println("Oops, out of gumballs!");
33                 gumballMachine.setState(gumballMachine.getSoldOutState());
34             }
35         }
36     }
37
38     public void refill() { }
39
40     public String toString() {
41         return "despensing two gumballs for your quarter, because YOU‘RE A WINNER!";
42     }
43 }

7.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class GumballMachine {
 4
 5     State soldOutState;
 6     State noQuarterState;
 7     State hasQuarterState;
 8     State soldState;
 9     State winnerState;
10
11     State state = soldOutState;
12     int count = 0;
13
14     public GumballMachine(int numberGumballs) {
15         soldOutState = new SoldOutState(this);
16         noQuarterState = new NoQuarterState(this);
17         hasQuarterState = new HasQuarterState(this);
18         soldState = new SoldState(this);
19         winnerState = new WinnerState(this);
20
21         this.count = numberGumballs;
22          if (numberGumballs > 0) {
23             state = noQuarterState;
24         }
25     }
26
27     public void insertQuarter() {
28         state.insertQuarter();
29     }
30
31     public void ejectQuarter() {
32         state.ejectQuarter();
33     }
34
35     public void turnCrank() {
36         state.turnCrank();
37         state.dispense();
38     }
39
40     void setState(State state) {
41         this.state = state;
42     }
43
44     void releaseBall() {
45         System.out.println("A gumball comes rolling out the slot...");
46         if (count != 0) {
47             count = count - 1;
48         }
49     }
50
51     int getCount() {
52         return count;
53     }
54
55     void refill(int count) {
56         this.count += count;
57         System.out.println("The gumball machine was just refilled; it‘s new count is: " + this.count);
58         state.refill();
59     }
60
61     public State getState() {
62         return state;
63     }
64
65     public State getSoldOutState() {
66         return soldOutState;
67     }
68
69     public State getNoQuarterState() {
70         return noQuarterState;
71     }
72
73     public State getHasQuarterState() {
74         return hasQuarterState;
75     }
76
77     public State getSoldState() {
78         return soldState;
79     }
80
81     public State getWinnerState() {
82         return winnerState;
83     }
84
85     public String toString() {
86         StringBuffer result = new StringBuffer();
87         result.append("\nMighty Gumball, Inc.");
88         result.append("\nJava-enabled Standing Gumball Model #2004");
89         result.append("\nInventory: " + count + " gumball");
90         if (count != 1) {
91             result.append("s");
92         }
93         result.append("\n");
94         result.append("Machine is " + state + "\n");
95         return result.toString();
96     }
97 }

8.

 1 package headfirst.designpatterns.state.gumballstatewinner;
 2
 3 public class GumballMachineTestDrive {
 4
 5     public static void main(String[] args) {
 6         GumballMachine gumballMachine =
 7             new GumballMachine(10);
 8
 9         System.out.println(gumballMachine);
10
11         gumballMachine.insertQuarter();
12         gumballMachine.turnCrank();
13         gumballMachine.insertQuarter();
14         gumballMachine.turnCrank();
15
16         System.out.println(gumballMachine);
17
18         gumballMachine.insertQuarter();
19         gumballMachine.turnCrank();
20         gumballMachine.insertQuarter();
21         gumballMachine.turnCrank();
22
23         System.out.println(gumballMachine);
24
25         gumballMachine.insertQuarter();
26         gumballMachine.turnCrank();
27         gumballMachine.insertQuarter();
28         gumballMachine.turnCrank();
29
30         System.out.println(gumballMachine);
31
32         gumballMachine.insertQuarter();
33         gumballMachine.turnCrank();
34         gumballMachine.insertQuarter();
35         gumballMachine.turnCrank();
36
37         System.out.println(gumballMachine);
38
39         gumballMachine.insertQuarter();
40         gumballMachine.turnCrank();
41         gumballMachine.insertQuarter();
42         gumballMachine.turnCrank();
43
44         System.out.println(gumballMachine);
45     }
46 }
时间: 2024-07-31 01:07:52

HeadFirst设计模式之状态模式的相关文章

软考总结— 设计模式之状态模式

软考在即,针对下午题的设计模式,本人有觉得有必要从考试战略上稍微做一些总结.为什么呢?一方面设计模式只要掌握好做题技巧,还是比较好拿分的.另一方面,通过这次软考又进一步的学习设计模式,而且在题目中给出的设计模式都是在项目中很好的应用. 一开始做题,没有全局观.俗话说的好"不谋全局者不足谋一域",不管做什么事,先在战略方向上把握好了,采取什么样的战术,都不成什么问题了.所以考试也是一样.下面这道题就很典型:   [题目] 某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,

设计模式之状态模式

<设计模式>对状态模式的定义:允许一个对象在其状态改变时,改变它的行为.看起来对象似乎修改了它的类.别名:状态对象(Objects for State). 在下面两种情况下均可以使用State模式: 1 一个对象的行为取决于它的状态,并且他必须在运行时刻根据状态改变它的行为. 2 一个操作中含有庞大的多分枝的条件语句,并且这些分支依赖于该对象的状态.这个状态通常用一个或多个枚举常量表示.通常,有多个操作包含这一相同的条件结构.State模式将每一个条件分支放入一个独立的类中.这是得你可以根据对

JAVA设计模式之 状态模式【State Pattern】

一.概述 当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式.状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化.状态模式是一种对象行为型模式. 二.适用场景 用于解决系统中复杂对象的多种状态转换以及不同状态下行为的封装问题.简单说就是处理对象的多种状态及其相互转换. 三.UML类图 四.参与者 1>.AbstractState(抽象状态类): 在抽象状态类中定义申明了不同状态下的行为抽象方法,而由子类

大话设计模式_状态模式(Java代码)

状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 简单描述:一个Context类(存有一个抽象状态State引用),调用状态类的方法.State的具体类方法中会判断Context类的状态(如时间),满足一个状态则执行相应动作,否则把Context的State引用指向下一个状态类,由下一个状态类决定相应行为 大话设计模式中的截图: 例子代码: Work类(Context): 1 package com.longsheng.state; 2 3 public cla

HeadFirst 设计模式 04 工厂模式

除了 new 操作符之外, 还有更多创造对象的方法. 工厂处理创建对象的细节. 这么做的目的是为了抽象, 例如把创建比萨的代码包装进一个类, 当以后实现改变时, 只需修改这个类即可. 利用静态方法定义一个简单的工厂, 这是很常见的技巧, 被称作静态工厂. 所有工厂模式斗都用来封装对象的创建, javascript 也是一样. 工厂方法模式通过让子类决定该创建的对象是什么, 来达到将对象创建的过程封装的目的. 工厂模式定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个. 工厂方法让类把实

设计模式之状态模式20170712

行为型设计模式之状态模式: 一.含义 为每个状态创建与之对应的类(对应的每个类实现同一个接口或继承同一个抽象类,便于统一处理),并且再通过一个类切换状态 二.代码说明 1.一般包含三个角色抽象状态角色,具体状态角色,以及环境(上下文)角色(负责具体状态的切换). 具体步骤: 1)定义环境角色,并初始化状态 2)通过环境角色执行行为,同时也就是对应状态的行为被执行 3)对应状态的行为的执行分为两种情况: I.对应状态对应行为执行后,环境角色继续执行行为,调用的还是此状态,此状态的下一个行为(下一状

【设计模式】状态模式 改进后的

1.简单谈谈 状态模式 当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类. 状态模式要解决的问题是:当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化. 优点:简化了一个对象的状态转换和行为改变的代码,把这部分代码放在了[状态类]中,需要注意的一点是:在[状态类]中,每个不同的[状态值]也许会被“串起来”成为一条链,这样就能保证设置不同的“离散的”[状态值]时,可以在“链上”有有个对应的处理(行为).

设计模式之状态模式(State)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

【C++实现】HeadFirst设计模式之策略模式

策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户. Head First设计模式中介绍策略模式时以Duck类作为例子,其中用flyBehavior和quackBehavior两个接口引用变量代表鸭子飞行和鸭子叫这两种行为,通过改变flyBehavior和quackBehavior来满足不同的Duck子类的不同行为,这样带来的好处就是可以在运行时改变Duck子类的行为.下面是我用C++改写的代码. //MyDuckMain.cpp #includ