行为型——备忘录模式C++实现

快照,允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

实例

Memento.h

#ifndef MEMENTO_H_
#define MEMENTO_H_

#include <string>

// 备忘录类保存编辑器的过往状态
class Snapshot {
 public:
    Snapshot(std::string text, int x, int y, double width)
        : text_(text), cur_x_(x), cur_y_(y), selection_width_(width) {}
    std::string get_text() {
        return text_;
    }
    int get_cur_x() {
        return cur_x_;
    }
    int get_cur_y() {
        return cur_y_;
    }
    double get_selection_width() {
        return selection_width_;
    }

 private:
    const std::string text_;
    const int cur_x_;
    const int cur_y_;
    const double selection_width_;
};

#endif  // MEMENTO_H_

即Snapshot类。 

Originator.h

#ifndef ORIGINATOR_H_
#define ORIGINATOR_H_

#include <cstdio>
#include <string>
#include <memory>
#include "Memento.h"

// 原发器中包含了一些可能会随时间变化的重要数据
// 它还定义了在备忘录中保存自身状态的方法, 以及从备忘录中恢复状态的方法
class Editor {
 public:
    void setText(std::string text) {
        text_ = text;
    }
    void setCursor(int x, int y) {
        cur_x_ = x;
        cur_y_ = y;
    }
    void setSelectionWidth(double width) {
        selection_width_ = width;
    }

    // 在备忘录中保存当前的状态
    std::shared_ptr<Snapshot> createSnapshot() {
        // 备忘录是不可变的对象, 因此原发器会将自身状态作为参数传递给备忘录的构造函数
        auto res = std::make_shared<Snapshot>(text_, cur_x_, cur_y_, selection_width_);
        printf("创建编辑器快照成功, text:%s x:%d y:%d width:%.2f\n", text_.c_str(), cur_x_, cur_y_, selection_width_);
        return res;
    }

    void resotre(std::shared_ptr<Snapshot> sptr_snapshot) {
        text_ = sptr_snapshot->get_text();
        cur_x_ = sptr_snapshot->get_cur_x();
        cur_y_ = sptr_snapshot->get_cur_y();
        selection_width_ = sptr_snapshot->get_selection_width();
        printf("恢复编辑器状态成功, text:%s x:%d y:%d width:%.2f\n", text_.c_str(), cur_x_, cur_y_, selection_width_);
    }

 private:
    // 文本
    std::string text_;
    // 光标位置
    int cur_x_;
    int cur_y_;
    // 当前滚动条位置
    double selection_width_;
};

#endif  // ORIGINATOR_H_

Caretaker.h

#ifndef CARETAKER_H_
#define CARETAKER_H_

#include <memory>
#include "Memento.h"
#include "Originator.h"

class Command {
 public:
    explicit Command(Editor* e) : editor_(e) {}
    void makeBackup() {
        backup_ = editor_->createSnapshot();
    }
    void undo() {
        if (backup_) {
            editor_->resotre(backup_);
        }
    }

 private:
    Editor *editor_;
    std::shared_ptr<Snapshot> backup_;
};

#endif  // CARETAKER_H_

Editor外面封装一层Command,Command可执行备份、恢复,对应Editor的备份、恢复。Command这层保证了Snapshot完全对外不可见。 

main.cpp

#include "Caretaker.h"

int main() {
    // 创建原发器和负责人
    Editor editor;
    Command command(&editor);

    // 定义初始状态
    editor.setText("TOMOCAT");
    editor.setCursor(21, 34);
    editor.setSelectionWidth(3.4);

    // 保存状态
    command.makeBackup();

    // 更改编辑器状态
    editor.setText("KKKK");
    editor.setCursor(111, 222);
    editor.setSelectionWidth(111.222);

    // 撤销
    command.undo();

    return 0;
}

编译运行:

$g++ -g main.cpp -o memento -std=c++11
$./memento
创建编辑器快照成功, text:TOMOCAT x:21 y:34 width:3.40
恢复编辑器状态成功, text:TOMOCAT x:21 y:34 width:3.40

猜你喜欢

转载自blog.csdn.net/weixin_36389889/article/details/130965550