通知图标

欢迎访问津桥芝士站

设计模式-备忘录-C++

该帖子部分内容已隐藏
付费阅读
3积分
此内容为付费阅读,请付费后查看
来自AI助手的总结
备忘录模式通过保存对象状态快照实现不暴露内部细节的状态恢复与撤销功能,适用于多种需要状态管理的应用场景。

一、引言

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不暴露对象内部状态的情况下保存和恢复对象的状态。这种模式通过备忘录对象来保存对象的内部状态,实现了对象状态的快照功能,常用于实现撤销操作。

二、使用场景

  1. 实现撤销/重做功能:在需要提供撤销和重做功能的应用程序中,如文本编辑器、绘图程序等,备忘录模式能够轻松实现这一需求。

  2. 状态记录与恢复:对于需要监控状态变化并能够恢复到先前状态的场景设计,备忘录模式提供了一种简便的方案。

  3. 数据较大时的快照:对于状态较多或复杂的对象,可以通过备忘录模式利用其快照功能方便地保存之前状态,方便后期检索和恢复。

  4. 构建时间和空间复杂度要求高的场景:可以通过备忘录进行内存优化,避免不必要的重复创建,同时合理保留对象的内部状态。

三、模式分类

  • 单备忘录:一个状态对应一个备忘录,备忘录存储的通常是某个对象的当前状态。
  • 多备忘录:为不同的状态创建多个备忘录,例如维护多个历史版本的快照。

四、优缺点

优点

  • 封装性:对象的内部状态被封装到备忘录中,调用者无法直接访问对象的内部数据。
  • 提醒撤销时巨大的灵活性:用户可以轻松撤销到任意先前状态,而不需要将状态保留在对象自身。
  • 简化原始对象:使得原始对象无需为实现撤销的操作而承担多余的复杂性。

缺点

  • 内存消耗:创建备忘录可能会消耗很多内存,特别是对于状态频繁变化的对象来说,一旦创建大量的备忘录会占用过多资源。
  • 实现复杂性:管理备忘录的生命周期可能使得代码复杂,尤其是在涉及多个对象及备忘录时,可能需要额外的管理逻辑。
  • 不支持时特复杂状态:如果需要深度对备忘录模式的支持,可能会需要借助额外的机制进行状态的监控和更改。

五、代码示例

以下是使用备忘录模式的C++实现示例。

#include <iostream>
#include <string>
#include <vector>
#include <memory>

// 备忘录类
class Memento {
private:
    std::string state; // 备忘录内部状态

public:
    explicit Memento(const std::string& state) : state(state) {} // 贮存状态的构造函数

    std::string getState() const {
        return state; // 获取状态
    }
};

// 原发器类
class Originator {
private:
    std::string state; // 当前状态

public:
    void setState(const std::string& state) {
        this->state = state; // 设置当前状态
    }

    std::string getState() const {
        return state; // 获取当前状态
    }

    // 创建备忘录
    std::shared_ptr<Memento> saveToMemento() {
        return std::make_shared<Memento>(this->state); // 保存当前状态
    }

    // 从备忘录恢复状态
    void restoreFromMemento(std::shared_ptr<Memento> memento) {
        state = memento->getState(); // 复原状态
    }
};

// 管理员类
class Caretaker {
private:
    std::vector<std::shared_ptr<Memento>> mementoList; // 备忘录容器

public:
    void addMemento(std::shared_ptr<Memento> memento) {
        mementoList.push_back(memento);
    }

    std::shared_ptr<Memento> getMemento(int index) const {
        if (index < 0 || index >= static_cast<int>(mementoList.size())) {
            throw std::out_of_range("Index out of range"); // 检查索引范围
        }
        return mementoList.at(index); // 获取指定备忘录
    }
};

int main() {
    Originator originator; // 创建原发器
    Caretaker caretaker; // 创建管理员

    // 设置状态并保存备忘录
    originator.setState("State 1");
    caretaker.addMemento(originator.saveToMemento());

    originator.setState("State 2");
    caretaker.addMemento(originator.saveToMemento());

    originator.setState("State 3");
    caretaker.addMemento(originator.saveToMemento());

    // 还原状态
    originator.restoreFromMemento(caretaker.getMemento(1)); // 还原为 State 2
    std::cout << "Restored to: " << originator.getState() << std::endl; // 输出当前状态

    return 0;
}

代码解析

  1. Memento:备忘录类,包含记录状态的属性和获取状态的方法。

  2. Originator:原发器类,负责设置和获取当前状态,支持保存状态到备忘录和从备忘录恢复状态。

  3. Caretaker:管理类,用于持有备忘录列表并负责保存和恢复备忘录。

  4. main():在主函数中,首先创建原发器和管理员对象,设置状态并生成备忘录,然后在需要时通过管理员获取备忘录,并使用原发器进行恢复。控制台输出恢复的状态。

六、模式总结

备忘录模式是管理对象状态的一种优雅方式,使得对象能够在不突破封装性的情况下进行状态恢复以及记录,常用于实现日志和撤销功能。尽管它有较高的内存消耗与管理复杂性等问题,但在合适的情况下,备忘录模式能够显著提高系统的灵活性、减少耦合,提供便捷的状态管理。理解和合理运用备忘录模式是软件设计中的一项重要技能,这有助于构建可维护和可扩展的应用系统。

请登录后发表评论

    没有回复内容