赶紧收藏!2024 年最常见 20道设计模式面试题(十)

上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(九)-CSDN博客

十九、备忘录模式如何实现对象状态的保存和恢复?

备忘录模式(Memento Pattern),也称为快照模式,是一种行为型设计模式,用于在不违反封装性的前提下,捕获并保存一个对象的内部状态,以便之后可以恢复到该状态。这种模式通常用于实现撤销操作或提供对象状态的历史回溯。

备忘录模式的定义:

备忘录模式提供了一种存储和恢复对象历史状态的方法,通过创建一个含有被保存状态的快照对象(备忘录),在不暴露对象内部实现细节的情况下,允许对象状态的恢复。

备忘录模式的组成:

  1. 发起人(Originator):负责创建一个备忘录,用以记录当前时刻的内部状态,并可以恢复到先前的状态。
  2. 备忘录(Memento):存储发起人对象的内部状态,并提供一个接口供负责人访问。
  3. 负责人(Caretaker):负责保存备忘录对象,但不能对备忘录内容进行操作或检查。

备忘录模式如何实现对象状态的保存和恢复:

  1. 状态封装:发起人对象创建一个备忘录对象,将当前的状态封装在其中,而不暴露其内部实现。

  2. 状态保存:负责人对象接收发起人提供的备忘录,并将其保存起来。负责人不关心备忘录的具体内容,只负责存储。

  3. 状态恢复:当需要恢复到之前的状态时,发起人对象从负责人那里获取备忘录,并使用备忘录中存储的状态信息恢复其内部状态。

  4. 保护封装性:备忘录模式确保了发起人对象的内部状态可以被保存和恢复,同时不破坏对象的封装性。

  5. 支持撤销操作:通过保存一系列的备忘录对象,可以实现撤销操作,即逐步恢复到之前的状态。

  6. 灵活性:备忘录模式允许在不同的时间点保存和恢复状态,提供了灵活性。

使用场景:

  • 当需要提供一个撤销功能,允许用户撤销他们的操作时。
  • 当需要保存一个对象的多个状态,以便在不同时间点进行恢复时。
  • 当对象的当前状态需要被其他对象访问,但又不想暴露对象的实现细节时。

示例:

假设我们有一个文本编辑器,需要实现撤销功能,允许用户撤销他们的编辑操作。

  1. 发起人TextEditor,负责创建备忘录,记录当前的文本状态,并可以恢复到之前的状态。
  2. 备忘录TextMemento,存储TextEditor的当前文本状态。
  3. 负责人HistoryManager,负责管理备忘录对象,保存和提供备忘录。

客户端代码可以这样使用备忘录模式:

TextEditor editor = new TextEditor();
editor.type("Hello, World!"); // 编辑文本
HistoryManager history = new HistoryManager();
history.save(editor.createMemento()); // 保存当前状态

editor.type("Kimi"); // 进一步编辑文本
editor.restore(history.getMemento()); // 撤销到之前的状态

在这个例子中,TextEditor是发起人,负责创建和恢复备忘录;TextMemento是备忘录,存储文本状态;HistoryManager是负责人,管理备忘录对象。通过这种方式,备忘录模式实现了对象状态的保存和恢复,同时保证了对象的封装性。

二十、策略模式如何实现算法的动态替换?

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换,算法的变化不会影响到使用算法的客户。策略模式主要用于实现算法的动态替换,即在运行时根据需要选择不同的算法。

策略模式的定义:

策略模式允许在运行时选择算法的行为,它将算法封装成对象,使得算法可以独立于使用它们的客户端变化。

策略模式的组成:

  1. 策略接口(Strategy Interface):定义了所有支持的算法的公共接口。
  2. 具体策略(Concrete Strategy):实现策略接口,提供具体的算法实现。
  3. 上下文(Context):使用策略接口作为其属性,维护一个对策略对象的引用,可以设置和更新策略。
  4. 客户端(Client):使用上下文对象来执行算法,客户端不直接与具体策略通信。

策略模式如何实现算法的动态替换:

  1. 算法封装:将每个算法封装为一个实现了策略接口的独立类,确保算法的独立性和可互换性。

  2. 运行时选择:上下文对象在运行时根据需要选择并设置具体策略对象,从而实现算法的动态替换。

  3. 解耦算法与使用算法的客户端:由于客户端通过上下文与策略接口交互,而不是直接与具体策略类交互,因此算法的变化不会影响到客户端。

  4. 扩展性:当需要添加新的算法时,只需创建一个新的具体策略类实现策略接口,而无需修改现有的代码。

  5. 灵活性:策略模式提供了高度的灵活性,允许在运行时根据条件或用户选择来改变算法的行为。

  6. 单一职责原则:每个具体策略类只负责一种算法的实现,符合单一职责原则。

使用场景:

  • 当需要在不同情况下使用不同的算法或行为,并且算法可能在运行时改变时。
  • 当算法的使用客户端不应该知道算法的具体实现细节时。
  • 当需要避免使用条件语句来在代码中切换算法时。

示例:

假设我们有一个排序程序,需要支持多种排序算法,如冒泡排序、选择排序和插入排序。

  1. 策略接口SortingStrategy,定义了一个sort方法。
  2. 具体策略BubbleSortSelectionSortInsertionSort,分别实现了SortingStrategy接口,提供了各自的排序算法实现。
  3. 上下文SortContext,包含一个SortingStrategy类型的属性,可以设置不同的排序策略,并执行排序。
  4. 客户端:使用SortContext来执行排序操作,客户端不直接与具体的排序算法交互。

客户端代码可以这样使用策略模式:

SortContext context = new SortContext();
context.setStrategy(new BubbleSort()); // 设置排序策略为冒泡排序
context.sort(); // 执行排序

context.setStrategy(new SelectionSort()); // 动态替换为选择排序
context.sort(); // 再次执行排序

在这个例子中,SortContext是上下文,负责执行排序操作;BubbleSortSelectionSortInsertionSort是具体策略,实现了不同的排序算法。通过策略模式,我们可以在运行时根据需要动态地替换排序算法,而无需修改客户端代码或上下文逻辑。这提供了高度的灵活性和可扩展性。

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值