状态模式
约 1423 字
预计阅读 3 分钟
次阅读
状态变化模式
- 什么是状态变化
- 在组件构建过程中, 某些对象的状态面临变化, 如何对这些变化进行有效的管理? 同时又保证高层的稳定?
- 典型模式
动机
-
在软件构建过程中, 某些对象的状态如果改变, 其行为也会随之而发生变化
- 比如文档处于只读状态, 其支持的行为和读写状态支持的行为就可能完全不同
-
如何在运行时根据对象的状态来透明的更改对象的行为? 而不会为对象操作和状态转化之间引入紧耦合?
模式定义
- 允许一个对象在其内部状态改变时改变他的行为, 从而使对象看起来似乎修改了其行为
代码示例
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
133
134
135
136
137
138
139
140
141
142
143
144
|
/* Author: ting
* Mail: vlicecream520@gmail.com
* Detail: (
* 1. 状态模式示例
* 一个程序员会随着一天的不同时间处于不同状态
*
* 2. 状态模式适用于 根据自己的状态发生变化 行为也随之发现变化
* 他跟观察者模式不一样 观察者模式是 一个或多个对象 根据 一个对象的状态发生变化而发生变化
* )
* */
#include <iostream>
using namespace std;
class Work;
// 状态接口
class State {
public:
// 与 work 行为相关的函数
virtual void WriteProgram(Work *w) = 0;
};
// 工作类
class Work {
private:
// 当前状态
State* current;
// 当前时间
double hour;
// 工作是否完成
bool taskFinish;
public:
Work() { taskFinish = false; }
// 设置/获取时间
void SetTime(double hour) { this->hour = hour; }
double GetTime() { return this->hour; }
// 设置状态
void SetState(State *s) { current = s; }
// 设置工程是否完成
void SetFinish() { this->taskFinish = true; }
// 获取工作是否完成状态
bool GetFinish() { return taskFinish; }
// work 行为
void WriteProgram() { current->WriteProgram(this); }
};
//下班休息状态
class RestState : public State {
public:
void WriteProgram(Work *w) { cout << "当前时间:" << w->GetTime() << "点 工作完成,下班回家了" << endl; }
};
//睡眠工作状态
class SleepingState : public State {
public:
void WriteProgram(Work *w) { cout << "受不了了," << w->GetTime() << "点了,先睡吧" << endl; }
};
//晚上工作状态
class EveningState : public State {
public:
void WriteProgram(Work *w) {
//任务完成了,可以休息了
if(w->GetFinish()) {
w->SetState(new RestState());
w->WriteProgram();
}
else {
if(w->GetTime()<21) { cout << "当前时间:" << w->GetTime() << "点 加班了,疲惫至极" << endl; }
else {
//找过21点
w->SetState(new SleepingState());
w->WriteProgram();
}
}
}
};
//下午工作状态
class AfternoonState : public State {
public:
void WriteProgram(Work *w) {
if(w->GetTime()<17) { cout << "当前时间:" << w->GetTime() << "点 状态还不错,继续努力" << endl; }
else {
w->SetState(new EveningState());
w->WriteProgram();
}
}
};
//中午工作状态
class NoonState : public State {
public:
void WriteProgram(Work *w)
{
if (w->GetTime()<13)
cout<<"当前时间:"<<w->GetTime()<<"点 饿了,午饭:犯困,午休"<<endl;
else
{
w->SetState(new AfternoonState());
w->WriteProgram();
}
}
};
//上午工作状态
class ForenoonState : public State {
public:
void WriteProgram(Work *w)
{
if(w->GetTime()<12)
cout<<"当前时间:"<<w->GetTime()<<"点 上午工作,精神百倍"<<endl;
else
{
w->SetState(new NoonState());
w->WriteProgram();
}
}
};
void main()
{
//紧急项目
Work *emergencyProjects = new Work();
emergencyProjects->SetState(new ForenoonState());
emergencyProjects->SetTime(9);
emergencyProjects->WriteProgram();
emergencyProjects->SetTime(10);
emergencyProjects->WriteProgram();
emergencyProjects->SetTime(12);
emergencyProjects->WriteProgram();
emergencyProjects->SetTime(14);
emergencyProjects->WriteProgram();
//完成工作,不需要再加班了
//emergencyProjects->SetFinish();
emergencyProjects->SetTime(19);
emergencyProjects->WriteProgram();
emergencyProjects->SetTime(22);
emergencyProjects->WriteProgram();
}
|
要点总结
- State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中, 在对象状态切换时, 切换相对应的对象,但同时维持State的接口, 这样实现了具体操作与状态转换之间的解藕
- 为不同的状态引入不同的对象使得状态转换变得更加明确, 而且可以保证不会出现状态不一致的情况, 因为转换是原子性的,即要么彻底转换过来 要么不转换
- 如果State对象没有实例变量, 那么各上下文可以共享一个State对象, 从而节省对象开销