C++备忘录模式:轻松实现状态回滚

备忘录模式的核心思想

备忘录模式(Memento Pattern)是一种行为设计模式,允许在不破坏封装性的前提下捕获并外部化对象的内部状态,以便后续可以恢复到该状态。该模式的核心在于分离状态保存与恢复的逻辑,避免直接暴露对象内部细节。

在C++中,备忘录模式通常涉及三个角色:

  • Originator(原发器):需要保存和恢复状态的对象。
  • Memento(备忘录):存储Originator的内部状态。
  • Caretaker(管理者):负责保存和管理Memento对象。

备忘录模式的实现步骤

定义Memento类 备忘录类需要保存Originator的部分或全部状态信息,通常设计为Originator的友元类以实现私有成员访问。

class Memento {
private:
    std::string state_;
    friend class Originator; // 允许Originator访问私有成员
    Memento(const std::string& state) : state_(state) {}
    std::string GetState() const { return state_; }
};

实现Originator类 Originator负责创建备忘录对象,并可通过备忘录恢复状态。关键方法包括CreateMemento()RestoreFromMemento()

class Originator {
private:
    std::string state_;
public:
    void SetState(const std::string& state) { state_ = state; }
    std::string GetState() const { return state_; }

    Memento CreateMemento() const {
        return Memento(state_);
    }

    void RestoreFromMemento(const Memento& memento) {
        state_ = memento.GetState();
    }
};

设计Caretaker类 Caretaker持有备忘录对象,但不直接操作其内容,仅负责存储和传递。

class Caretaker {
private:
    Memento memento_;
public:
    void SaveMemento(const Memento& memento) { memento_ = memento; }
    Memento RetrieveMemento() const { return memento_; }
};

使用场景与代码示例

典型场景

  • 需要实现撤销/重做功能(如文本编辑器)。
  • 需要保存对象的历史状态(如游戏存档)。
  • 需要隔离状态管理的职责。

完整示例代码 以下示例展示文本编辑器的撤销操作实现:

#include <iostream>
#include <string>
#include <stack>

class TextMemento {
private:
    std::string text_;
    friend class TextEditor;
    TextMemento(const std::string& text) : text_(text) {}
    std::string GetText() const { return text_; }
};

class TextEditor {
private:
    std::string text_;
public:
    void Type(const std::string& words) { text_ += words; }
    TextMemento Save() const { return TextMemento(text_); }
    void Restore(const TextMemento& memento) { text_ = memento.GetText(); }
    void Print() const { std::cout << "Current text: " << text_ << std::endl; }
};

class History {
private:
    std::stack<TextMemento> stack_;
public:
    void Push(const TextMemento& memento) { stack_.push(memento); }
    TextMemento Pop() {
        TextMemento top = stack_.top();
        stack_.pop();
        return top;
    }
};

int main() {
    TextEditor editor;
    History history;

    editor.Type("Hello, ");
    history.Push(editor.Save());
    editor.Print();

    editor.Type("World!");
    history.Push(editor.Save());
    editor.Print();

    editor.Restore(history.Pop());
    editor.Print(); // 输出恢复到"Hello, "
}

模式优缺点分析

优点

  • 保持封装边界,不暴露Originator内部实现。
  • 简化Originator职责,状态管理由Caretaker处理。
  • 支持多状态备份,易于实现撤销机制。

缺点

  • 频繁保存状态可能导致内存占用过高。
  • Caretaker需管理Memento生命周期,可能引入复杂性。
  • 部分语言(如C++)需借助友元机制,破坏一定的封装性。

进阶应用与变体

增量备忘录 仅保存状态变化部分而非完整状态,减少存储开销。适用于大型对象的状态管理。

class IncrementalMemento {
private:
    int delta_; // 记录变化量而非完整状态
    friend class Counter;
    IncrementalMemento(int delta) : delta_(delta) {}
    int GetDelta() const { return delta_; }
};

多级撤销 通过栈或列表结构存储多个备忘录,支持多步撤销。示例中的History类即采用栈结构实现。

与命令模式结合 将备忘录作为命令的执行结果保存,实现原子化操作的回滚。常用于事务系统设计。

BbS.okacop081.info/PoSt/1120_525713.HtM
BbS.okacop082.info/PoSt/1120_767657.HtM
BbS.okacop083.info/PoSt/1120_298861.HtM
BbS.okacop084.info/PoSt/1120_024063.HtM
BbS.okacop085.info/PoSt/1120_409789.HtM
BbS.okacop086.info/PoSt/1120_461952.HtM
BbS.okacop087.info/PoSt/1120_684026.HtM
BbS.okacop088.info/PoSt/1120_262049.HtM
BbS.okacop090.info/PoSt/1120_594169.HtM
BbS.okacop091.info/PoSt/1120_361138.HtM
BbS.okacop081.info/PoSt/1120_051419.HtM
BbS.okacop082.info/PoSt/1120_789335.HtM
BbS.okacop083.info/PoSt/1120_471365.HtM
BbS.okacop084.info/PoSt/1120_862229.HtM
BbS.okacop085.info/PoSt/1120_831700.HtM
BbS.okacop086.info/PoSt/1120_098263.HtM
BbS.okacop087.info/PoSt/1120_992310.HtM
BbS.okacop088.info/PoSt/1120_771674.HtM
BbS.okacop090.info/PoSt/1120_540544.HtM
BbS.okacop091.info/PoSt/1120_593128.HtM
BbS.okacop081.info/PoSt/1120_675670.HtM
BbS.okacop082.info/PoSt/1120_153838.HtM
BbS.okacop083.info/PoSt/1120_051426.HtM
BbS.okacop084.info/PoSt/1120_459458.HtM
BbS.okacop085.info/PoSt/1120_143700.HtM
BbS.okacop086.info/PoSt/1120_854771.HtM
BbS.okacop087.info/PoSt/1120_363895.HtM
BbS.okacop088.info/PoSt/1120_360018.HtM
BbS.okacop090.info/PoSt/1120_862442.HtM
BbS.okacop091.info/PoSt/1120_060684.HtM
BbS.okacop092.info/PoSt/1120_313423.HtM
BbS.okacop093.info/PoSt/1120_820578.HtM
BbS.okacop094.info/PoSt/1120_558348.HtM
BbS.okacop095.info/PoSt/1120_775809.HtM
BbS.okacop096.info/PoSt/1120_555253.HtM
BbS.okacop097.info/PoSt/1120_922193.HtM
BbS.okacop098.info/PoSt/1120_822732.HtM
BbS.okacop099.info/PoSt/1120_883552.HtM
BbS.okacop114.info/PoSt/1120_024975.HtM
BbS.okacop829.info/PoSt/1120_362712.HtM
BbS.okacop092.info/PoSt/1120_067014.HtM
BbS.okacop093.info/PoSt/1120_290908.HtM
BbS.okacop094.info/PoSt/1120_246211.HtM
BbS.okacop095.info/PoSt/1120_953977.HtM
BbS.okacop096.info/PoSt/1120_085351.HtM
BbS.okacop097.info/PoSt/1120_330098.HtM
BbS.okacop098.info/PoSt/1120_159440.HtM
BbS.okacop099.info/PoSt/1120_739539.HtM
BbS.okacop114.info/PoSt/1120_622642.HtM
BbS.okacop829.info/PoSt/1120_477091.HtM
BbS.okacop092.info/PoSt/1120_641112.HtM
BbS.okacop093.info/PoSt/1120_486190.HtM
BbS.okacop094.info/PoSt/1120_621734.HtM
BbS.okacop095.info/PoSt/1120_383701.HtM
BbS.okacop096.info/PoSt/1120_098690.HtM
BbS.okacop097.info/PoSt/1120_686358.HtM
BbS.okacop098.info/PoSt/1120_168481.HtM
BbS.okacop099.info/PoSt/1120_710570.HtM
BbS.okacop114.info/PoSt/1120_062971.HtM
BbS.okacop829.info/PoSt/1120_879629.HtM
BbS.okacop092.info/PoSt/1120_679885.HtM
BbS.okacop093.info/PoSt/1120_043933.HtM
BbS.okacop094.info/PoSt/1120_005312.HtM
BbS.okacop095.info/PoSt/1120_248026.HtM
BbS.okacop096.info/PoSt/1120_017272.HtM
BbS.okacop097.info/PoSt/1120_210867.HtM
BbS.okacop098.info/PoSt/1120_441167.HtM
BbS.okacop099.info/PoSt/1120_237952.HtM
BbS.okacop114.info/PoSt/1120_030346.HtM
BbS.okacop829.info/PoSt/1120_798457.HtM
BbS.okacop092.info/PoSt/1120_811535.HtM
BbS.okacop093.info/PoSt/1120_178577.HtM
BbS.okacop094.info/PoSt/1120_410739.HtM
BbS.okacop095.info/PoSt/1120_684747.HtM
BbS.okacop096.info/PoSt/1120_367621.HtM
BbS.okacop097.info/PoSt/1120_347081.HtM
BbS.okacop098.info/PoSt/1120_694822.HtM
BbS.okacop099.info/PoSt/1120_347572.HtM
BbS.okacop114.info/PoSt/1120_073951.HtM
BbS.okacop829.info/PoSt/1120_149482.HtM

#牛客AI配图神器#

全部评论

相关推荐

11-11 16:40
已编辑
门头沟学院 人工智能
不知道怎么取名字_:这个有点不合理了,相当于已经毕业了,但还是没转正,这不就是白嫖
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务