C++设计模式 之 “状态变化” 模式:State、Memento

  “状态变化”模式

  在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模式为这一问题提供了一种解决方案。
  典型模式
  # state
  # memento

  Part 1 State 状态模式
  动机
  #在软件构建过程中,某些对象的状态如果改变,其行为也会随之而变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
  #如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
  #避免代码的坏味道——Long Method
  模式定义
  允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。——《设计模式》GoF
  结构
 

  结构 from 《大话设计模式》

  代码 未使用State模式 from 《大话设计模式》

 1 void work(int clock, TASK_FINISH task) {
 2     if (clock < 12)
 3     {
 4         cout << "上午"<<endl;
 5     }
 6     else if (clock < 13)
 7     {
 8         cout << "中午" << endl;
 9     }
10     else if (clock < 17)
11     {
12         cout << "下午" << endl;
13     }
14     else 
15     {
16         if (task == true)
17         {
18             cout << "下班" << endl;
19         }
20         else
21         {
22             if (clock < 21)
23             {
24                 cout << "晚上,加班" << endl;
25             }
26 
27             cout << "好累,睡着了" << endl;
28         }
29     }
30 }
31 
32 int main() {
33     
34     work(9, false);
35     work(12, false);
36     work(15, false);
37     work(18, false);
38 
39     return 0;
40 }
View Code

  代码 State模式 from 《大话设计模式》

 1 #include <string>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 struct Context;
 7 struct State {
 8     virtual void work(Context c) = 0;
 9 };
10 
11 struct Context {
12     bool taskFinish = false;
13     unsigned clock = 6;
14     State* _state;
15     void work() { this->_state->work(*this); }
16 };
17 
18 struct SleepState : public State {
19     virtual void work(Context c) override {
20         cout << "sleeping..." << endl;
21     }
22 };
23 
24 struct EveningState : public State {
25     virtual void work(Context c) override {
26         if (c.taskFinish == true)
27             cout << "back home" << endl;
28         else
29         {
30             if (c.clock < 21)
31                 cout << "evening" << endl;
32             else
33                 c._state = new SleepState();
34         }
35     }
36 };
37 
38 struct AfternoonState : public State {
39     virtual void work(Context c) override {
40         if (c.clock < 17)
41             cout << "afternoon" << endl;
42         else
43             c._state = new EveningState();
44     }
45 };
46 
47 struct NoonState : public State {
48     virtual void work(Context c) override {
49         if (c.clock < 13)
50             cout << "noon" << endl;
51         else
52             c._state = new AfternoonState();
53     }
54 };
55 
56 struct ForenoonState : public State {
57     virtual void work(Context c) override {
58         if (c.clock < 12)
59             cout << "forenoon" << endl;
60         else
61             c._state = new NoonState();
62     }
63 };
64 
65 int main() {
66     Context project;
67     project._state = new ForenoonState();
68 
69     project.work();
70 
71     project.clock = 12;
72     project.work();
73 
74     project.clock = 14;
75     project.work();
76 
77     project.clock = 18;
78     project.work();
79 
80     return 0;
81 }
View Code

  要点总结
  #State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
  #为不同的状态引入不同的对象,使得状态转化变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换时原子性的——即要么彻底转换过来,要么不转换。
  #如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。

posted @ 2015-12-01 22:12  健康平安快乐  阅读(487)  评论(0编辑  收藏  举报