zoukankan      html  css  js  c++  java
  • 备忘录模式笔记

    备忘录模式

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

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

    备忘录模式的结构图

    备忘录模式包含的角色:

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

    缺点:

    资源消耗过大。

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

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

  • 相关阅读:
    k8s
    vue-element-admin实现模板打印
    MAC系统命令
    思维导图工具
    前端如何渲染几万条数据不卡住页面?
    Echar使用案例
    .Net 相关报错解决方案
    Windows 操作技巧
    Docker&K8s
    微信网页授权原理分析
  • 原文地址:https://www.cnblogs.com/bxtfdxg/p/12940073.html
Copyright © 2011-2022 走看看