备忘录模式

# 分类

行为型模式

# 定义

  • 备忘录模式(Memento Pattern) 保存一个对象的某个状态,以便在适当的时候恢复对象的状态。

# 意图

在不破坏封装性的提前下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

# 应用场景

  • 需要保存/恢复数据的相关状态场景。
  • 提供一个可回滚操作的场景。

实用案例

  • 后悔药。
  • 打游戏时的存档。
  • Windows的Ctrl+Z。
  • IE中的后退。
  • 数据库的事务管理。

# 角色与结构图

  • Originator:发起人角色 负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的哪些内部状态。
  • Memento:备忘录角色 负责储存Originator对象的内部状态,并可防止 Originator 以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。 Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
  • Caretaker:管理者角色 负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

下图解释了备忘录模式中各角色的作用

<<------------------------备忘录模式结构图--------------------------->>

# 示例代码

//发起者
class Originator {
  private string state;
  public string State{
    get{return this.state;}
    set{this.state = value;}
  }

  public Memento CreateMemento(){
    return new Memento(this.state);
  }

   public void SetMemento(Menento memento){
    state = memento.State;
  }

  public void Show(){
    Console.WriteLine("State = "+ State);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//备忘录
class Memento{
  private string state;

  public Memento(string state){
    this.state = state;
  }

  public string Stete{
    get{ return this.state;}
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
//管理者
class Caretaker{
  private Memento memento;

  public Memento Memento{
    get{ return this.memento;}
    set{ memento = value;}
  }
}
1
2
3
4
5
6
7
8
9
//客户端
class Client{
    public static void Main(string[] args) {
    Originator o =  new Originator();
    o.state = "On";
    o.Show();

    Caretaker c = new Caretaker();
    c.Memento = c.CreateMement();

    O.State = "Off";
    o.Show();

    o.SetMemento(c.Memento);
    o.Show();

    Console.ReadLine();
  }   
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 优点

  • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史状态。
  • 实现了信息的封装,使得用户不需要关心状态的保存细节

# 缺点

  • 消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

# 小结

  • 把要保存的细节封装在Memento中,这样需要更改保存的细节也不用影响客户端了。

  • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。

  • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态

  • 有时一些对象的内部信息必须保存在对象以外的地方,但是必须由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来,从而可以恰当地保存封装的边界。

  • 备忘录模式的最大作用在于当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

  • 主要解决?所谓备忘录模式就是在不破坏封装的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态

  • 何时使用?很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。

  • 如何解决?通过一个备忘录类专门存储对象状态。

  • 关键代码?客户不与备忘录类耦合,与备忘录管理类耦合

# 一句话概括

存储系统某一时刻的状态,并在合适的时机将其恢复。

上次更新: 2025/03/22, 13:47:44
最近更新
01
Git问题集合
01-29
02
安装 Nginx 服务器
01-25
03
安装 Docker 容器
01-25
更多文章>
×
×