状态模式

说明

  • 定义
    状态模式,允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
  • 角色
    1. context应用环境:内部持有多个state的引用以及代表当前状态的应用
    2. state状态接口:定义了所有具体状态的共同接口,任何状态都要实现这个接口,以便,状态之间相互替代。
    3. concreteState具体状态:处理来自context的请求,每个concreteState都提供了自己对于请求的实现,所有,当context改变状态是,行为也会跟着改变。
  • 优点
    1. 它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
    2. 它使得状态转换显式化
    3. State对象可被共享
  • 缺点
    1. 状态模式的使用必然会增加系统类和对象的个数。
    2. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  • 应用场景
    一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
    代码中包含大量与对象状态有关的条件语句
  • 状态模式与策略模式:
    1. 两者类图相同。
    2. 两者意图不同。
    3. 状态模式中,context的行为可以委托到所有状态中的任意一个,一般地,当前状态会自发地再各个状态之间游走(比如:饿,吃饭,到饱),不必context去特意指定。而且,context内会包含多个state的引用。
    4. 在策略模式中,context通常为了实现某一种算法、策略,会自动指定特定的策略对象。一般,context只包含一个策略对象的引用。
    5. 一般来说,我们把策略模式想成是除里继承之外的一种弹性替代方案。而把状态模式想成是不用再context中放置许多判断条件的替代方案。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* 猪的状态接口
*
* @author sky
*
*/
public interface PigState {

public void eat();

public void sleep();

}

/**
* 猪饿的状态
*
* @author sky
*
*/
public class HungerState implements PigState {

private Pig pig;

public HungerState(Pig pig) {
this.pig = pig;
}

@Override
public void eat() {
System.out.println("猪饿了,吃食。。。。。变饱了。");
pig.setNowState(pig.getFull());
}

@Override
public void sleep() {
System.out.println("猪饿了,睡不着。");
}

}

/**
* 猪饱的状态
*
* @author sky
*
*/
public class FullState implements PigState {

private Pig pig;

public FullState(Pig pig) {
this.pig = pig;
}

@Override
public void eat() {
System.out.println("猪很饱,吃不下。");
}

@Override
public void sleep() {
System.out.println("猪睡了一觉。。。。又饿了。");
pig.setNowState(pig.getHunger());
}

}


/**
* 猪
*
* @author sky
*
*/
public class Pig {

private PigState hunger;

private PigState full;

private PigState nowState;

public Pig() {
hunger = new HungerState(this);
full = new FullState(this);
nowState = hunger;
}

public PigState getNowState() {
return nowState;
}

public void setNowState(PigState nowState) {
this.nowState = nowState;
}

public void eat() {
nowState.eat();
}

public void sleep() {
nowState.sleep();
}

public PigState getHunger() {
return hunger;
}

public PigState getFull() {
return full;
}
}

/**
* 测试类
*
* @author sky
*
*/
public class Test {


public static void main(String[] args) {
Pig pig = new Pig();
pig.sleep();
pig.eat();
pig.eat();
pig.sleep();

}
}

输出

1
2
3
4
猪饿了,睡不着。
猪饿了,吃食。。。。。变饱了。
猪很饱,吃不下。
猪睡了一觉。。。。又饿了。