0%

设计模式之状态模式和备忘录

设计模式基础(11):状态模式&备忘录

包含状态模式&备忘录两种模式中的C++示例代码、面向的问题、图解两种模式核心思想

状态模式

面向的需求

  • 当一个对象的状态发生变化,其操作也跟着发生变化。

示例代码

原始代码

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
enum NetworkState
{
Network_Open,
Network_Close,
Network_Connect,
};

class NetworkProcessor{

NetworkState state;

public:

void Operation1(){
if (state == Network_Open){

//**********
state = Network_Close;
}
else if (state == Network_Close){

//..........
state = Network_Connect;
}
else if (state == Network_Connect){

//$$$$$$$$$$
state = Network_Open;
}
}

public void Operation2(){

if (state == Network_Open){

//**********
state = Network_Connect;
}
else if (state == Network_Close){

//.....
state = Network_Open;
}
else if (state == Network_Connect){

//$$$$$$$$$$
state = Network_Close;
}

}

public void Operation3(){

}
};

利用状态模式重构之后

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
class NetworkState{

public:
NetworkState* pNext;
virtual void Operation1()=0;
virtual void Operation2()=0;
virtual void Operation3()=0;

virtual ~NetworkState(){}
};

class OpenState :public NetworkState{

static NetworkState* m_instance;
public:
static NetworkState* getInstance(){
if (m_instance == nullptr) {
m_instance = new OpenState();
}
return m_instance;
}

void Operation1(){

//**********
pNext = CloseState::getInstance();
}

void Operation2(){

//..........
pNext = ConnectState::getInstance();
}

void Operation3(){

//$$$$$$$$$$
pNext = OpenState::getInstance();
}


};

class CloseState:public NetworkState{ }
//...

class NetworkProcessor{

NetworkState* pState;

public:

NetworkProcessor(NetworkState* pState){

this->pState = pState;
}

void Operation1(){
//...
pState->Operation1();
pState = pState->pNext;
//...
}

void Operation2(){
//...
pState->Operation2();
pState = pState->pNext;
//...
}

void Operation3(){
//...
pState->Operation3();
pState = pState->pNext;
//...
}

};

代码思想分析

状态模式

分析:

  • 在初始代码下,先判定当前状态然后执行操作,之后状态转移。包含大量的if_else判断。
  • 采用状态模式之后,将状态的判断转换为子类的类型。复写相应的操作,还可以指定每一个子类状态的下一个子类状态。从而实现在扩展时,主体部分是稳定的,只需要扩展子类。

关键点

  • 为不同的状态引入不同的对象,切换对象就是切换相应的状态。

备忘录

面向的需求

  • 当需要记录主体运行过程中的状态,额外引入一种类来进行记录。

示例代码

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
class Memento
{
string state;
//..
public:
Memento(const string & s) : state(s) {}
string getState() const { return state; }
void setState(const string & s) { state = s; }
};

class Originator
{
string state;
//....
public:
Originator() {}
Memento createMomento() {
Memento m(state);
return m;
}
void setMomento(const Memento & m) {
state = m.getState();
}
};

int main()
{
Originator orginator;

//捕获对象状态,存储到备忘录
Memento mem = orginator.createMomento();

//... 改变orginator状态

//从备忘录中恢复
orginator.setMomento(memento);
}

关键点

  • 目前拥有一些新的技术(如序列化等),这种模式的上述代码形式的应用很少,大都采用新技术。