设计模式 - State 模式(状态模式)
作用:允许一个对象在其内部状态改变时改变它的行为。
UML结构图:
解析:
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题,而这样的问题,大部分人是采用switch-case语句进行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代码进行编译.State模式采用了对这些不同的状态进行封装的方式处理这类问题,当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责任交给了具体的状态类去负责.同时,State模式和Strategy模式在图示上有很多相似的地方,需要说明的是两者的思想都是一致的,只不过封装的东西不同:State模式封装的是不同的状态,而Stategy模式封装的是不同的算法。
代码实现:
State.h
1 #ifndef STATE_H
2 #define STATE_H
3
4 class State;
5
6 class Context
7 {
8 public:
9 Context(State* pState);
10 ~Context();
11 void Request();
12 void ChangeState(State *pState);
13
14 private:
15 State *m_pState;
16 };
17
18 class State
19 {
20 public:
21 virtual ~State(){}
22
23 virtual void Handle(Context* pContext) = 0;
24 };
25
26 class ConcreateStateA
27 : public State
28 {
29 public:
30 void Handle(Context* pContext);
31 };
32
33 class ConcreateStateB
34 : public State
35 {
36 public:
37 void Handle(Context* pContext);
38 };
39
40 #endif
41
2 #define STATE_H
3
4 class State;
5
6 class Context
7 {
8 public:
9 Context(State* pState);
10 ~Context();
11 void Request();
12 void ChangeState(State *pState);
13
14 private:
15 State *m_pState;
16 };
17
18 class State
19 {
20 public:
21 virtual ~State(){}
22
23 virtual void Handle(Context* pContext) = 0;
24 };
25
26 class ConcreateStateA
27 : public State
28 {
29 public:
30 void Handle(Context* pContext);
31 };
32
33 class ConcreateStateB
34 : public State
35 {
36 public:
37 void Handle(Context* pContext);
38 };
39
40 #endif
41
State.cpp
1
2 #include "State.h"
3 #include <iostream>
4
5 Context::Context(State* pState)
6 : m_pState(pState)
7 {
8
9 }
10
11 Context::~Context()
12 {
13 delete m_pState;
14 m_pState = NULL;
15 }
16
17 void Context::Request()
18 {
19 if (NULL != m_pState)
20 {
21 m_pState->Handle(this);
22 }
23 }
24
25 void Context::ChangeState(State *pState)
26 {
27 if (NULL != m_pState)
28 {
29 delete m_pState;
30 m_pState = NULL;
31 }
32
33 m_pState = pState;
34 }
35
36 void ConcreateStateA::Handle(Context* pContext)
37 {
38 std::cout << "Handle by ConcreateStateA\n";
39
40 if (NULL != pContext)
41 {
42 pContext->ChangeState(new ConcreateStateB());
43 }
44 }
45
46 void ConcreateStateB::Handle(Context* pContext)
47 {
48 std::cout << "Handle by ConcreateStateB\n";
49
50 if (NULL != pContext)
51 {
52 pContext->ChangeState(new ConcreateStateA());
53 }
54 }
55
2 #include "State.h"
3 #include <iostream>
4
5 Context::Context(State* pState)
6 : m_pState(pState)
7 {
8
9 }
10
11 Context::~Context()
12 {
13 delete m_pState;
14 m_pState = NULL;
15 }
16
17 void Context::Request()
18 {
19 if (NULL != m_pState)
20 {
21 m_pState->Handle(this);
22 }
23 }
24
25 void Context::ChangeState(State *pState)
26 {
27 if (NULL != m_pState)
28 {
29 delete m_pState;
30 m_pState = NULL;
31 }
32
33 m_pState = pState;
34 }
35
36 void ConcreateStateA::Handle(Context* pContext)
37 {
38 std::cout << "Handle by ConcreateStateA\n";
39
40 if (NULL != pContext)
41 {
42 pContext->ChangeState(new ConcreateStateB());
43 }
44 }
45
46 void ConcreateStateB::Handle(Context* pContext)
47 {
48 std::cout << "Handle by ConcreateStateB\n";
49
50 if (NULL != pContext)
51 {
52 pContext->ChangeState(new ConcreateStateA());
53 }
54 }
55
Main.cpp
1 #include "State.h"
2
3 int main()
4 {
5 State *pState = new ConcreateStateA();
6 Context *pContext = new Context(pState);
7 pContext->Request();
8 pContext->Request();
9 pContext->Request();
10
11 delete pContext;
12
13 return 0;
14 }
2
3 int main()
4 {
5 State *pState = new ConcreateStateA();
6 Context *pContext = new Context(pState);
7 pContext->Request();
8 pContext->Request();
9 pContext->Request();
10
11 delete pContext;
12
13 return 0;
14 }