备忘录模式小结

备忘录模式是在不破坏封装的原则下,捕获一个对象的状态,在对象之外保存这个状态,在必要时恢复到这个状态。

应用场景主要是将状态恢复到之前,例如Ctrl+Z的恢复,游戏从存档重新开始,JDBC事务控制。

备忘录模式的主要角色有三个:

Originator,发起人,职责是发起一次存档,将自身的状态存放到Memeto里面;

Memento,备忘录,存储Originator的状态;

Caretaker,负责人,负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。

个人理解,Memento可以看作是Originator的一个副本,最简单的不用模式的方法,就是在Originator实现Clone接口,使用时Clone一个副本出来。

示例代码:

复制代码
 1 package com.khlin.memento;
 2 
 3 /**
 4  * 魂斗罗
 5  * @author Kingsley
 6  *
 7  */
 8 public class Contra {
 9     
10     /*
11      * 剩下几条命
12      */
13     private int life;
14     
15     /*
16      * 手上的武器
17      */
18     private String weapon;
19 
20     public Contra(int life, String weapon) {
21         this.life = life;
22         this.weapon = weapon;
23     }
24     
25     public int getLife() {
26         return this.life;
27     }
28     
29     public String getWeapon() {
30         return this.weapon;
31     }
32     
33     public Memento createMemento() {
34         return new Memento(life, weapon);
35     }
36     
37     public void restoreMemento(Memento memento) {
38         this.life = memento.getLife();
39         this.weapon = memento.getWeapon();
40     }
41     
42     public void die() {
43         this.life = 0;
44         this.weapon = null;
45     }
46 }
复制代码
复制代码
 1 package com.khlin.memento;
 2 
 3 public class Memento {
 4     
 5     private int life;
 6     
 7     private String weapon;
 8     
 9     public Memento(int life, String weapon) {
10         this.life = life;
11         this.weapon = weapon;
12     }
13     
14     public int getLife() {
15         return this.life;
16     }
17     
18     public String getWeapon() {
19         return this.weapon;
20     }
21 }
复制代码
复制代码
 1 package com.khlin.memento;
 2 
 3 /**
 4  * 备忘录的管理器
 5  * @author Kingsley
 6  *
 7  */
 8 public class Caretaker {
 9     
10     private Memento memento;
11 
12     public Memento getMemento() {
13         return memento;
14     }
15 
16     public void setMemento(Memento memento) {
17         this.memento = memento;
18     }
19 }
复制代码

客户端调用:

复制代码
 1 package com.khlin.memento;
 2 
 3 public class App {
 4     
 5     public static void main(String[] args) {
 6         Contra contra = new Contra(10, "AK47");
 7         System.out.println("battle begins!!!");
 8         System.out.println("contra life " + contra.getLife() + " weapon " + contra.getWeapon());
 9         
10         System.out.println("saving memento......");
11 
12         Caretaker caretaker = new Caretaker();
13         Memento memento = contra.createMemento();
14         caretaker.setMemento(memento);;
15         
16         System.out.println("save memento successfully!!");
17         
18         contra.die();
19         
20         System.out.println("contra dies. life " + contra.getLife() + " weapon " + contra.getWeapon());
21         
22         System.out.println("restoring memento....");
23         
24         contra.restoreMemento(caretaker.getMemento());
25         
26         System.out.println("restore memento successfully!!");
27         
28         System.out.println("contra life " + contra.getLife() + " weapon " + contra.getWeapon());
29     }
30 }
复制代码

运行结果:

优点:

· 提供了状态的恢复机制

· 提供了状态保存状态的方法,用户不需要关心状态的保存实现

缺点:

· 消耗资源

 

应用场景:

备忘录模式又叫快照(snapshot)模式,因此可以用于需要保存某一时刻的状态的场景。

此外, 如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过负责人可以间接访问其内部状态。

 

posted @   kingsleylam  阅读(423)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示