长沙的网站建设,ppt模板免费下载图片,农业网站模板免费下载,淘宝网网页版登录设计模式20-备忘录 动机定义与结构定义结构 C代码推导优缺点应用场景总结备忘录模式和序列化备忘录模式1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 序列化1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 对比总结 动机
在软件构建过… 设计模式20-备忘录 动机定义与结构定义结构 C代码推导优缺点应用场景总结备忘录模式和序列化备忘录模式1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 序列化1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 对比总结 动机
在软件构建过程中某些对象的状态在转换过程中可能由于某种需要这个程序能够回溯到对象之前处于某个点时的状态。使用一些公用接口来让其他对象得到对象的状态便会暴露对象细节的实现如何实现对象状态的良好保存与恢复但同时又不会因此而破坏对象本身的封装性呢。在软件开发中有时需要在不破坏对象封装性的前提下捕获并存储对象的内部状态以便稍后可以将对象恢复到以前的状态。这种需求通常出现在实现撤销/恢复操作的场景中例如文本编辑器中的撤销操作。直接暴露对象的内部状态会违反封装原则而备忘录模式提供了一种解决方案使得状态恢复操作能够在不破坏封装性的前提下实现。
定义与结构
定义
备忘录模式在不破坏封装性的前提下捕获对象的内部状态并在该对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态。
结构 解释这张图
这张图描绘了一个典型的UML统一建模语言结构图展示了“备忘录模式”Memento Pattern的核心组件及其关系。备忘录模式是一种用于捕获和存储一个对象内部状态的方式以便可以在未来某个时刻将对象恢复到这个状态。这个模式特别适用于需要保存和恢复对象状态的场景比如撤销操作、事务处理等。
图中包含了三个主要的类 Originator原发器这个类是需要被保存状态的对象。它包含一个CreateMemento()方法用于创建一个备忘录对象Memento这个对象包含了Originator的当前状态。Originator还包含一个SetMemento(Memento m)方法用于设置Originator的状态为备忘录对象Memento中存储的状态。图中对SetMemento方法的描述可能有些误解因为通常这个方法不会直接从外部传入一个备忘录对象来设置状态而是由Caretaker或者系统其他部分将之前保存的备忘录对象传递回Originator来恢复状态。 Memento备忘录这个类用于存储Originator的内部状态以保护这些状态不受外部访问。它包含了一个构造函数尽管图中没有直接标出该构造函数可能接受来自Originator的当前状态作为参数。Memento还包含GetState()和SetState(state)方法尽管图中SetState方法的参数可能标记有误通常备忘录模式中的Memento类不需要SetState方法因为备忘录主要是用来存储状态的。但在实际实现中GetState()方法用于返回备忘录中存储的状态而SetState如果存在的话可能并不是Memento类的一部分而是用于在Originator中恢复状态的过程中的一部分但这通常是通过将Memento对象传递给Originator的某个恢复状态方法来实现的。 Caretaker管理者这个类负责保存备忘录对象但不检查备忘录对象的内容。在图中Caretaker类被描述为有一个ReturnNewMemento(state)方法这实际上可能是一个误解或错误。在标准的备忘录模式中Caretaker类会维护一个备忘录对象的列表但不直接创建新的Memento对象。相反它可能包含一个AddMemento(Memento m)方法来添加新的备忘录对象以及一个GetMemento(index)或类似的方法来检索之前保存的备忘录对象。图中的ReturnNewMemento(state)可能试图表达Caretaker返回一个新状态的Memento对象给Originator但这并不是Caretaker类的典型职责更常见的是Caretaker简单地存储和检索Memento对象。
图中箭头表示类之间的交互关系。从Originator到Memento的箭头表示Originator创建Memento对象的过程而从Caretaker到Originator的箭头尽管图中没有直接画出表示Caretaker可能将存储的Memento对象传递回Originator以恢复状态。
需要注意的是图中的某些细节如ReturnNewMemento(state)方法和SetState0方法的标记可能与标准的备忘录模式实现不完全一致可能是为了简化图示或特定实现的表示。
C代码推导
以下是一个简单的备忘录模式的C实现示例模拟一个文本编辑器的撤销功能。
备忘录类
#include iostream
#include string// 备忘录类用于存储Originator的内部状态
class Memento {
private:std::string state;public: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::cout State set to: state std::endl;}std::string getState() const {return state;}Memento* createMemento() {return new Memento(state);}void setMemento(Memento* memento) {state memento-getState();std::cout State restored to: state std::endl;}
};负责人类
class Caretaker {
private:Memento* memento;public:void saveMemento(Memento* memento) {this-memento memento;}Memento* getMemento() {return memento;}~Caretaker() {delete memento;}
};客户端代码
int main() {Originator* originator new Originator();Caretaker* caretaker new Caretaker();originator-setState(State1);caretaker-saveMemento(originator-createMemento());originator-setState(State2);caretaker-saveMemento(originator-createMemento());originator-setState(State3);// 恢复到上一个状态originator-setMemento(caretaker-getMemento());delete originator;delete caretaker;return 0;
}运行结果
State set to: State1
State set to: State2
State set to: State3
State restored to: State2优缺点
优点
封装性备忘录模式可以在不破坏对象封装性的前提下保存和恢复对象的状态符合对象的封装原则。简化撤销操作备忘录模式简化了复杂系统中的撤销操作实现使得对象能够恢复到先前的状态。
缺点
内存开销如果对象的状态较大且备忘录创建频繁可能会占用大量内存增加系统开销。管理复杂性备忘录需要被妥善管理尤其是在需要多个备忘录进行多步撤销时备忘录的管理和恢复可能会变得复杂。
应用场景
备忘录模式在以下场景中应用较多
需要保存对象状态以便恢复例如实现多步撤销/恢复功能的场景如文本编辑器、图形编辑器等。需要避免暴露对象内部状态当需要避免外部直接访问对象的内部状态时可以使用备忘录模式来实现状态保存和恢复。对象状态变化复杂且不可预测在对象状态变化频繁且不可预测的情况下备忘录模式可以有效管理这些状态变化。
总结
备忘录模式是一种强大的设计模式通过封装对象的内部状态实现了状态的保存和恢复功能。虽然它能够有效地支持撤销和恢复操作但在实际应用中需要注意内存消耗和管理复杂性特别是在对象状态复杂且变化频繁的场景下。备忘录模式存储原发器对象的内部状态。在需要时恢复原发器状态。备忘录模式的核心是信息隐藏即原发器需要向外界隐藏信息保持其封装性但同时又需要将再保存到外界。由于现代语言运行时如JAVA c#都具有相当的对象序列化支持。因此往往采用效率较高又较容易正确实现的序列化方案来实现备忘录模式。
备忘录模式和序列化
备忘录模式和序列化在某些方面具有相似的功能但它们的目标和应用场景不同。
备忘录模式
1. 动机
备忘录模式的主要动机是保存和恢复对象的内部状态而不破坏对象的封装性。它常用于实现撤销/恢复操作让对象能够恢复到之前的某个状态。
2. 实现方式
备忘录模式通过创建一个“备忘录”对象将发起人Originator对象的内部状态存储在该备忘录对象中。发起人可以使用这个备忘录对象来恢复其内部状态。备忘录模式通常包括三个角色发起人、备忘录和负责人Caretaker其中负责人仅负责管理备忘录的保存和恢复不直接访问备忘录的内容。
3. 应用场景
撤销/恢复操作如文本编辑器、图形编辑器中的撤销功能。历史记录管理需要保存对象的状态以便以后恢复。避免对象内部状态暴露需要保存和恢复对象状态时但不希望暴露对象的内部实现。
4. 优点
封装性备忘录模式可以在不破坏对象封装性的前提下保存和恢复状态。简单性对外界来说状态的保存和恢复过程是透明的简化了撤销/恢复功能的实现。
5. 缺点
内存消耗如果对象的状态较大或备忘录频繁创建可能会导致较大的内存开销。管理复杂性当涉及多个状态备忘录时备忘录的管理可能会变得复杂。
序列化
1. 动机
序列化的主要目的是将对象的状态转换为字节流以便可以将其存储在文件、数据库或通过网络传输并在以后将其反序列化为原始对象。
2. 实现方式
序列化将对象的状态转换为字节流并将其保存到存储介质中。反序列化则是将字节流重新转换为对象。序列化通常依赖于语言或平台提供的内置机制如Java的Serializable接口或C的自定义序列化逻辑。
3. 应用场景
持久化存储将对象状态保存到文件或数据库中以便以后恢复。网络传输在分布式系统中将对象状态通过网络传输到另一个系统。跨平台数据交换不同平台之间的数据交换需要将对象状态转换为通用的字节流格式。
4. 优点
持久性序列化使得对象状态可以长期保存并在需要时恢复。跨平台序列化后的数据可以在不同平台或系统之间传输和共享。
5. 缺点
性能开销序列化和反序列化可能会引入性能开销特别是在大型对象或频繁操作的情况下。安全性序列化数据可能会暴露对象的内部状态存在安全风险如果反序列化的对象来自不可信的来源可能会导致安全漏洞。
对比总结 用途不同 备忘录模式主要用于保存和恢复对象的状态以支持撤销/恢复操作强调对象的封装性。序列化主要用于持久化或跨网络传输对象的状态强调对象的持久性和可传输性。 实现方式不同 备忘录模式通常是在内存中保存对象的状态并通过备忘录对象管理状态的保存和恢复。序列化将对象的状态转换为字节流存储在外部介质中或通过网络传输。 封装性 备忘录模式注重保持对象的封装性外部系统无法访问对象的内部状态。序列化通常会暴露对象的内部状态可能会引发安全问题。 应用场景不同 备忘录模式适用于需要频繁保存和恢复对象状态的场景如撤销功能。序列化适用于对象的持久化存储、网络传输、跨平台数据交换等场景。
备忘录模式更适合在应用程序内部管理对象的状态转换而序列化更适合在应用程序与外部系统之间交换或持久化数据。两者可以结合使用例如在分布式系统中备忘录模式管理对象状态而序列化用于将状态持久化或传输到其他节点。