首页 > 其他 > 详细

备忘录模式笔记

时间:2020-05-23 00:50:17      阅读:121      评论:0      收藏:0      [点我收藏+]

备忘录模式

 

定义:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。(提供江湖人称的后悔药,可以回到以前某个状态。)

动机:为了允许用户取消不确定的操作或从错误中恢复过来,需要设置备份点并提供撤销机制,而要实现这些机制,要事先将状态信息保存在某处,这样才能将对象恢复到它们原先的状态

 

 

备忘录模式的结构图

 

技术分享图片

 

备忘录模式包含的角色:

 

1.原发器(Originator)

原发器可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态。

 

2.备忘录(Memento)

存储原发器的内部状态,根据原发器来决定保存哪些内部状态。(除了原发器本身和负责人类之外,备忘录对象不能直接供其他类使用,所以这里的类不能设为public

 

3.负责人(Caretaker)

负责保存备忘录,但是不能对备忘录的内容进行操作或检查。(只负责存储,不能修改!!!)

 

 

 

 

-------------------------------------------------------------我是最渣的分割线---------------------------------------------------------------------

下面是一个例题

某软件公司正在开发一款RPG网游,为了给玩家提供更多方便,在游戏过程中设置一个恢复点,用于保存当前的游戏场景,如果在后续游戏过程中玩家角色“不幸牺牲”,可以返回到先前保存的场景,从所设恢复点开始重新游戏。试使用备忘录模式设计该功能,要求绘制相应的类图并使用Java语言编程模拟实现。

(因为老师要求保存多个状态,故在负责人类那里以数组形式对备忘录进行了存储)

 

以下是自己的代码实现

 

原发器类

技术分享图片
 1 package RPG;
 2 
 3 public class PlayeuserInfo {// 原发器
 4     private String blood;// 血量
 5     private String blue;// 蓝色法力
 6     private String heroname;//英雄名称
 7 
 8     public String getBlood() {
 9         return blood;
10     }
11 
12     public void setBlood(String blood) {
13         this.blood = blood;
14     }
15 
16     public String getBlue() {
17         return blue;
18     }
19 
20     public void setBlue(String blue) {
21         this.blue = blue;
22     }
23     public String getHeroName() {
24         return heroname;
25     }
26 
27     public void setHeroName(String heroName) {
28         heroname = heroName;
29     }
30 
31     public Memento saveMemento() {// 保存备忘录
32         return new Memento(heroname,blood, blue);
33     }
34 
35     public void restoreMemento(Memento memento) {// 重置备忘录
36         this.blood = memento.getBlood();
37         this.blue = memento.getBlue();
38         this.heroname=memento.getHeroName();
39     }
40 
41     public void show() {// 展示现在的状态
42         System.out.println(heroname+"现在的血量为" + this.blood + ",法力值为:" + this.blue);
43 
44     }
45 
46 
47 
48 }
View Code

这里原发器,封装了英雄名称,血量,法力值,也增加了保存备忘录和从备忘录中恢复状态的方法。

 

 

备忘录类

技术分享图片
 1 package RPG;
 2 
 3 class Memento {
 4     private String blood;// 血量
 5     private String blue;// 蓝色法力
 6     private String heroname;// 英雄名称
 7 
 8     public Memento(String heroname,String blood, String blue) {
 9         // TODO Auto-generated constructor stub
10         this.blood = blood;
11         this.blue = blue;
12         this.heroname = heroname;
13     }
14 
15     public String getBlood() {
16         return blood;
17     }
18 
19     public void setBlood(String blood) {
20         this.blood = blood;
21     }
22 
23     public String getBlue() {
24         return blue;
25     }
26 
27     public void setBlue(String blue) {
28         this.blue = blue;
29     }
30 
31     public String getHeroName() {
32         return heroname;
33     }
34 
35     public void setHeroName(String heroName) {
36         this.heroname = heroName;
37     }
38 
39 }
View Code

这里因为要存储和原发器类对应的字段,因此它的成员属性和getter,setter方法都要和原发器的一样,而且要和原发器类放在同一个包,因为不能让其他类对他直接访问,故这个类不能设为public。

 

 

负责人类

技术分享图片
 1 package RPG;
 2 
 3 import java.util.ArrayList;
 4 
 5 public class Memento_Caretaker {
 6     private ArrayList  mementolist=new ArrayList();//用一个集合把所有的备忘录存储起来
 7 
 8     public Memento getMemento(int i) {//获取备忘录
 9         return (Memento) mementolist.get(i);
10     }
11 
12     public void setMemento(Memento memento) {//设置备忘录
13         mementolist.add(memento);
14     }
15 }
View Code

负责人类也放在和前两个同一个包里面,但外部可以直接访问,负责人只负责存储,不能修改。

这里用了ArrayList数组形式保存多个备忘录。通过getMemento()方法来获取备忘录,通过add()方法向数组设置/增加备忘录。

 

 

客户端类

技术分享图片
 1 package RPG;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         // TODO Auto-generated method stub
 7         PlayeuserInfo user = new PlayeuserInfo();
 8         Memento_Caretaker mc = new Memento_Caretaker();
 9 
10         user.setHeroName("王昭君");
11         user.setBlood("5000");
12         user.setBlue("5000");
13         System.out.println("状态一:");
14         user.show();
15         mc.setMemento(user.saveMemento());// 保存备忘录
16         System.out.println("-----------------------------------");
17 
18         user.setHeroName("王昭君");
19         user.setBlood("4280");
20         user.setBlue("1000");
21         System.out.println("状态二:");
22         user.show();
23         mc.setMemento(user.saveMemento());// 保存备忘录
24         System.out.println("-----------------------------------");
25         
26         user.setHeroName("王昭君");
27         user.setBlood("2500");
28         user.setBlue("2000");
29         System.out.println("状态三:");
30         user.show();
31         mc.setMemento(user.saveMemento());// 保存备忘录
32         System.out.println("-----------------------------------");
33 
34         System.out.println("!!!!玩家不幸牺牲!!!!");
35         user.restoreMemento(mc.getMemento(0));
36         System.out.println("回到状态一");
37         user.show();
38         System.out.println("-----------------------------------");
39     }
40 
41 }
View Code

在客户端类这里进行原发器的创建以及负责人的创建,设置备忘录的属性,并进行保存和恢复。

 

输出结果:

技术分享图片

 

 

备忘录模式的优缺点

优点:

(1)提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用先前存储起来的备忘录将状态复原。

(2)实现了信息的封装,一个备忘录对象是一种原发器对象的表示,不会被其他代码改动,这种模式简化了原发器对象,备忘录只保存原发器的状态,采用堆栈来存储备忘录对象可以实现多次撤销操作,可以通过在负责人中定义集合对象来存储多个备忘录。

 

缺点:

资源消耗过大。

 

备忘录模式的适用情况包括

保存一个对象在某一个时刻的状态或部分状态,这样以后需要时它能够恢复到先前的状态;如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

 

备忘录模式笔记

原文:https://www.cnblogs.com/bxtfdxg/p/12940073.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!