状态模式简单例子

最近在看《重构》,第一章的例子就用到了State模式来重构一段代码。State模式的结构还笔记好理解,所以就试着写一个简单的例子。

State模式的思想

首先有一个抽象的基类State,在其中定义了一些接口。State的派生类实现了这些接口,每个派生类的操作各不同。另外,还有一个类Context,类中有一个成员State,通过这个成员来表示Context所处的状态。Context可以改变不同的状态,从而对外展示出不同的特性。(这里的类名随意取的)

代码

State类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef TSTATEMODE_STATE_H_
#define TSTATEMODE_STATE_H_

namespace tstatemode {

class State {
public:
virtual ~State() {};
virtual void Handle() = 0;
};

} // namespace tstatemode

#endif // TSTATEMODE_STATE_H_

State类中就定义了一个Handle接口。

子类ConcreteState1头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef TSTATEMODE_CONCRETE_STATE1_H_
#define TSTATEMODE_CONCRETE_STATE1_H_

#include "state.h"

namespace tstatemode {

class ConcreteState1: public State {
public:
virtual ~ConcreteState1();
virtual void Handle();
};

} // namespace tstatemode

#endif // TSTATEMODE_CONCRETE_STATE1_H_

子类ConcreteState1源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "concrete_state1.h"

#include <stdio.h>

namespace tstatemode {

ConcreteState1::~ConcreteState1() { }

void ConcreteState1::Handle() {
printf("ConcreteState1 %s\n", __FUNCTION__);
}

} // namespace tstatemode

子类ConcreteState2头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef TSTATEMODE_CONCRETE_STATE2_H_
#define TSTATEMODE_CONCRETE_STATE2_H_

#include "state.h"

namespace tstatemode {

class ConcreteState2: public State {
public:
virtual ~ConcreteState2();
virtual void Handle();
};

} // namespace tstatemode

#endif // TSTATEMODE_CONCRETE_STATE2_H_

子类ConcreteState2源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "concrete_state2.h"

#include <stdio.h>

namespace tstatemode {

ConcreteState2::~ConcreteState2() { }

void ConcreteState2::Handle() {
printf("ConcreteState2 %s\n", __FUNCTION__);
}

} // namespace tstatemode

Context类头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef TSTATEMODE_CONTEXT_H_
#define TSTATEMODE_CONTEXT_H_

#include "state.h"

namespace tstatemode {

class Context {
public:
Context(State* state): state_(state) {}
bool ChangeState(State* state);
void Display();
private:
State* state_;
};

} // namespace tstatemode

#endif // TSTATEMODE_CONTEXT_H_

Context类源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "context.h"

namespace tstatemode {

bool Context::ChangeState(State* state) {
if(nullptr != state) state_ = state;
return true;
}

void Context::Display() {
if(nullptr != state_)
state_->Handle();
}

} // namespace tstatemode

主函数:

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
#include "context.h"
#include "concrete_state1.h"
#include "concrete_state2.h"
#include "state.h"

int main() {
namespace tsm = tstatemode;

tsm::State* state1 = new tsm::ConcreteState1();
tsm::State* state2 = new tsm::ConcreteState2();
tsm::Context context(state1);

context.Display();

context.ChangeState(state2);
context.Display();

context.ChangeState(state1);
context.Display();

delete state1;
delete state2;

return 0;
}