找回密码
 立即注册
首页 业界区 业界 [设计模式]行为型-备忘录模式

[设计模式]行为型-备忘录模式

蔺堰 2025-6-6 14:52:58
简介

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许生成对象状态的快照并在以后将其还原。备忘录模式不会影响它所处理对象的内部结构,也不会影响快照中存储的数据。简单来说,它就像游戏中的“保存”和“加载”功能。
组成角色:

  • Originator(发起人): 主要用于生成自身状态的快照,在需要时可以通过快照恢复自身状态。
  • Memento(备忘录): 一个对象,用于存储Originator在某个特定时间点的内部状态。备忘录对Originator之外的对象是不可见的,这样可以保护Originator的状态不被外部修改。通常将备忘录类设置为不可变的类,并且通过构造函数一次性传递数据。
  • Caretaker(管理者): 负责保存和管理备忘录对象,但不检查备忘录的内容,只知道何时和为何捕捉Originator的状态,以及何时恢复Originator的状态。
常见使用场景


  • 撤销/重做功能: 许多应用程序(如文本编辑器、图形编辑器)都提供了撤销和重做操作。备忘录模式可以用来保存每次操作之前的状态,以便进行撤销。
  • 事务管理: 在某些事务处理系统中,可能需要在事务失败时回滚到之前的状态。备忘录模式可以用来保存事务开始前的状态。
  • 程序状态的快照和恢复: 有时需要定期保存程序的状态,以便在出现问题时能够恢复到最近的稳定状态。
  • 游戏中的保存和加载: 游戏通常需要保存玩家的进度,并在需要时加载。备忘录模式非常适合这种场景。
优点


  • 封装性好: Originator的状态被封装在Memento中,对外部不可见,保证了状态的安全性。
  • 简化了Originator: Originator只需要负责创建和恢复备忘录,而不需要关心备忘录的管理。备忘录的管理交由Caretaker负责。
  • 支持历史版本: 可以保存Originator的多个历史状态,方便进行多次撤销或恢复。
缺点


  • 内存消耗: 如果需要保存的状态很多或者状态很大,可能会消耗大量的内存。
  • 管理复杂性: Caretaker需要管理多个备忘录对象,可能会增加管理的复杂性。
  • 状态恢复的性能开销: 恢复状态可能涉及到复杂的数据复制操作,可能会有一定的性能开销。
示例代码

Simple

Go
  1. package memento
  2. type Memento struct {
  3.         state int
  4. }
  5. func NewMemento(value int) *Memento {
  6.         return &Memento{
  7.                 state: value,
  8.         }
  9. }
  10. type Originator struct {
  11.         value int
  12. }
  13. func NewOriginator(value int) *Originator {
  14.         return &Originator{
  15.                 value: value,
  16.         }
  17. }
  18. func (o *Originator) TenTimes() {
  19.         o.value *= 10
  20. }
  21. func (o *Originator) HalfTimes() {
  22.         o.value /= 2
  23. }
  24. func (o *Originator) Value() int {
  25.         return o.value
  26. }
  27. func (o *Originator) CreateMemento() *Memento {
  28.         return NewMemento(o.value)
  29. }
  30. func (o *Originator) RestoreMemento(m *Memento) {
  31.         o.value = m.state
  32. }
  33. type Caretaker struct {
  34.         Mementos []*Memento
  35. }
  36. func (c *Caretaker) AddMemento(m *Memento) {
  37.         c.Mementos = append(c.Mementos, m)
  38. }
  39. func (c *Caretaker) GetMemento(index int) *Memento {
  40.         return c.Mementos[index]
  41. }
复制代码
客户端
  1. package memento
  2. import (
  3.         "fmt"
  4.         "testing"
  5. )
  6. func TestSimple(t *testing.T) {
  7.         caretaker := &Caretaker{
  8.                 Mementos: make([]*Memento, 0),
  9.         }
  10.         n := NewOriginator(10)
  11.         caretaker.AddMemento(n.CreateMemento())
  12.         n.TenTimes()
  13.         fmt.Printf("Current value: %d\n", n.Value())
  14.         caretaker.AddMemento(n.CreateMemento())
  15.         n.TenTimes()
  16.         fmt.Printf("Current value: %d\n", n.Value())
  17.         n.RestoreMemento(caretaker.GetMemento(0))
  18.         fmt.Printf("Current value after restore: %d\n", n.Value())
  19. }
复制代码
执行输出
  1. Current value: 100
  2. Current value: 1000
  3. Current value after restore: 10
复制代码
Python
  1. from typing import List
  2. class Memento:
  3.     """
  4.     备忘录类
  5.     """
  6.     def __init__(self, value: int):
  7.         self._value = value
  8.     @property
  9.     def value(self) -> int:
  10.         """用 property 实现属性只读"""
  11.         return self._value
  12. class Originator:
  13.     """
  14.     发起人类
  15.     """
  16.     def __init__(self, value: int):
  17.         self._value = value
  18.     def ten_times(self):
  19.         self._value *= 10
  20.     def half_times(self):
  21.         self._value /= 2
  22.     def get_value(self) -> int:
  23.         return self._value
  24.     def create_memento(self) -> Memento:
  25.         return Memento(self._value)
  26.     def restore_memento(self, memento: Memento):
  27.         self._value = memento.value
  28. class Caretaker:
  29.     """负责人类"""
  30.     def __init__(self):
  31.         self._mems: List[Memento] = []
  32.     def add_memento(self, memento: Memento):
  33.         self._mems.append(memento)
  34.     def get_memento(self, index: int) -> Memento:
  35.         return self._mems[index]
  36. if __name__ == "__main__":
  37.     caretaker = Caretaker()
  38.     n = Originator(10)
  39.     caretaker.add_memento(n.create_memento())
  40.     n.ten_times()
  41.     print(f"current value: {n.get_value()}")
  42.     caretaker.add_memento(n.create_memento())
  43.     n.ten_times()
  44.     print(f"current value: {n.get_value()}")
  45.     n.restore_memento(caretaker.get_memento(0))
  46.     print(f"current value after restore: {n.get_value()}")
复制代码
执行输出
  1. current value: 100
  2. current value: 1000
  3. current value after restore: 10
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册