目录

状态变化_Memento


状态变化”模式

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

典型模式

  • state
  • memento

1 memento

实现的技术已经不是现代语言所需要的了, 现在的对象序列化的方式发生了很大的变化. 但是这个模式的思想还是很有用的.

1.1 模式动机

在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。

如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。

1.2 模式定义

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。

1.3 模式示例代码

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

// 备忘录类:文本状态
class TextState {
public:
    TextState(const std::string& text) : text(text) {}

    std::string getText() const {
        return text;
    }

private:
    std::string text;
};

// 发起人类:文本编辑器
class TextEditor {
public:
    void setText(const std::string& text) {
        this->text = text;
    }

    std::string getText() const {
        return text;
    }

    // 创建备忘录,保存当前状态
    TextState createMemento() const {
        return TextState(text);
    }

    // 恢复备忘录,回到指定状态
    void restoreMemento(const TextState& state) {
        text = state.getText();
    }

private:
    std::string text;
};

// 管理者类:撤销恢复管理器
class UndoRedoManager {
public:
    void saveState(const TextState& state) {
        states.push_back(state);
    }

    TextState undo() {
        if (!states.empty()) {
            TextState state = states.back();
            states.pop_back();
            return state;
        }
        return TextState("");
    }

private:
    std::vector<TextState> states;
};

int main() {
    TextEditor editor;
    UndoRedoManager manager;

    // 设置文本内容
    editor.setText("Hello, World!");

    // 保存初始状态
    TextState initialState = editor.createMemento();
    manager.saveState(initialState);

    // 修改文本内容
    editor.setText("Hello, Design Patterns!");

    // 保存修改后的状态
    TextState modifiedState = editor.createMemento();
    manager.saveState(modifiedState);

    // 撤销操作
    TextState undoState = manager.undo();
    editor.restoreMemento(undoState);
    std::cout << "撤销后的文本内容:" << editor.getText() << std::endl;

    return 0;
}

2 要点总结

备忘录(Memento)存储原发器 (Originator)对象的内部状态, 在需要时恢复原发器状态。

Memento 模式的核心是信息隐藏,即 Originator 需要向外接隐藏信息,保持其封装性。但同时又需要将状态保持到外界 (Memento)

电于现代语言运行时(如 C#、Java 等)都具有相当的对象序列化支持,因此往往采用效率较高、又较容易正确实现的序列化方案来实现 Memento 模式。