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 }

  代码 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 }

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

时间: 2024-10-25 05:30:35

C++设计模式 之 “状态变化” 模式:State、Memento的相关文章

设计模式之状态模式(State)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

【Unity与23种设计模式】备忘录模式(Memento)

GoF中定义: "在不违反封装的原则下,获取一个对象的内部状态并保留在外部,让对象可以在日后恢复到原先保留时的状态." 对于一些需要存储的数据,比如历史最高分 当与得分减分系统写入一个类时,违反了单一职责原则 最好是做一个SaveData的类单独存储或获取 而当使用一个单独的类时,又必须将数据public向外公开 这就将游戏置于危险的境地,甚至是方便了外挂横行 针对此矛盾局势 备忘录模式便解决了这一问题 备忘录模式可以描述为: 在不增加各个游戏系统类成员的"存取"方

设计模式:备忘录模式(Memento)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将对象恢复到原先保存的状态. 备忘录模式的角色: 1. 原发器(Originator):负责创建一个备忘录,用以记录当前对象的内部状态,通过也可以使用它来利用备忘录回复内部状态.同时原发器还可以根据需要决定Memento存储Originator的那些内部状态. 2. 备忘录(Memento):用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento.在备忘录Meme

JAVA设计模式之 备忘录模式【Memento Pattern】

一.概述 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后将对象恢复至原先保存的状态.它是一种对象行为型模式. 二.适用场景 1.类似于撤销功能的实现,保存一个对象在某一时间的部分状态或全部状态,当以后需要它时就可以恢复至先前的状态. 2. 对对象历史状态的封装.避免将对象的历史状态的实现细节暴露给外界. 三.UML类图 四.参与者 1.Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内

设计模式 ( 十七) 状态模式State(对象行为型)

1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得“力不从心了”.随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,关门,停,

[设计模式] 20 状态模式 State Pattern

在GOF的<设计模式:可复用面向对象软件的基础>一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.状态模式的重点在于状态转换,很多时候,对于一个对象的状态,我们都是让这个对象包含一个状态的属性,这个状态属性记录着对象的具体状态,根据状态的不同使用分支结构来执行不同的功能,就像上面的代码那样处理:就像上面说的,类中存在大量的结构类似的分支语句,变得难以维护和理解.状态模式消除了分支语句,就像工厂模式消除了简单工厂模式的分支语句一样,将状态处理分散

C#设计模式(23)——备忘录模式(Memento Pattern)

一.引言 在上一篇博文分享了访问者模式,访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而今天要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘录模式保存的是发起人的状态(而状态对应的数据结构,如属性).下面具体来看看备忘录模式. 二.备忘录模式介绍 2.1 备忘录模式的定义 从字面意思就可以明白,备忘录模式就是对某个类的状态进行保存下来,等到需要恢复的时候,可以从备忘录中进行恢复.生活中这样的例子经

【设计模式】—— 状态模式State

前言:[模式总览]——————————by xingoo 模式意图 允许一个对象在内部改变它的状态,并根据不同的状态有不同的操作行为. 例如,水在固体.液体.气体是三种状态,但是展现在我们面前的确实不同的感觉.通过改变水的状态,就可以更改它的展现方式. 应用场景 1 当一个对象的行为,取决于它的状态时 2 当类结构中存在大量的分支,并且每个分支内部的动作抽象相同,可以当做一种状态来执行时. 模式结构 Context 环境角色,里面包含状态对象 class Context{ private Sta

23种设计模式之备忘录模式(Memento)

备忘录模式确保在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态.备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤. 优点: 1)保持封装的完整. 2)简化了返回到初始状态所需的操作. 使用场景: 1)必须保存对象状态的快照,这样以后就可以恢复状态. 2)使用直接接口来获得状态可能会公开对象的实现细节,从而破坏对象的封装性. Memento 模式