设计模式基础(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.setMomento(memento); }
|
关键点
- 目前拥有一些新的技术(如序列化等),这种模式的上述代码形式的应用很少,大都采用新技术。