zoukankan      html  css  js  c++  java
  • 【设计模式】备忘录模式

    背景:

           这几天,几个和我一样即将要考软考的同僚来找我,找我讨论设计模式——备忘录模式。

           说起这个话,我瞬时就想起来了一个游戏,3D坦克大战。当时咱们还比较小,上课也是闲着难受,就跟几个同学一起玩这个游戏,那个场面,那是相当的好玩,而且有一点特别好的就是,能够保存游戏进度。怎么说呢,就是当我进行到分值最高,状态最好(血值最高、魔值最高、弹药最充足)的时候,进行保存。然后就在此放心去打坦克,当什么时候状态更好,分值更高的情况下,再次保存一个进度;什么时候亘屁了(挂了),最起码不用再辛辛苦苦的从头来过,直接还原一个状态就可以了,那啥那啥,少奋斗二十年呢!

           就这么个例子,现在回想一下,完全符合我们的备忘录模式的设计思想!作为游戏发起者,我——操作者(Operator),当我状态超好的时候,我创建一个游戏进度保存实体进行状态保存。当我不行了的时候,我又把这个已经保存好的状态还原到我游戏上的人物上去(大坦克);

    什么是备忘录模式:

    定义:

           在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态。

           从定义中不难看出,我们这个模式是为了完成一个状态保存,然后能够完成状态还原的这么一个东西,所以肯定是行为类(设计模式分创建型、结构型、行为型三类)的一个设计模式。

    类图:

                

           从这个类图分析一下子,我们的发起人这个Originator类,里面有两个方法,一个是保存当前的状态,另一个是还原状态(setMernento);而所谓的备忘录这个类其实是一个实体类,用来接收创建的数据和承接还原状态前的数据存放问题。而Caretaker类呢,其实就是你游戏里面的的存储游戏状态的那个容器+你的主观意识,因为你要从这里面去确认一个想要还原的状态,取出来,然后再通过本人的setMernerto方法去进行状态还原。

    举一个简单的例子,我们肯定都会使用,但是不保定都能意识到,就是我们的ctrl+z。自己想一下吧。

    备忘录模式结构:

    发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。

    备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。

    管理角色:对备忘录进行管理,保存和提供备忘录。

    代码分析:

    1. class Originator {    
    2.     private String state = "";    
    3.         
    4.     public String getState() {    
    5.         return state;    
    6.     }    
    7.     public void setState(String state) {    
    8.         this.state = state;    
    9.     }    
    10.     public Memento createMemento(){    
    11.         return new Memento(this.state);    
    12.     }    
    13.     public void restoreMemento(Memento memento){    
    14.         this.setState(memento.getState());    
    15.     }    
    16. }    
    17.     
    18. class Memento {    
    19.     private String state = "";    
    20.     public Memento(String state){    
    21.         this.state = state;    
    22.     }    
    23.     public String getState() {    
    24.         return state;    
    25.     }    
    26.     public void setState(String state) {    
    27.         this.state = state;    
    28.     }    
    29. }    
    30. class Caretaker {    
    31.     private Memento memento;    
    32.     public Memento getMemento(){    
    33.         return memento;    
    34.     }    
    35.     public void setMemento(Memento memento){    
    36.         this.memento = memento;    
    37.     }    
    38. }    
    39. public class Client {    
    40.     public static void main(String[] args){    
    41.         Originator originator = new Originator();    
    42.         originator.setState("状态1");    
    43.         System.out.println("初始状态:"+originator.getState());    
    44.         Caretaker caretaker = new Caretaker();    
    45.         caretaker.setMemento(originator.createMemento());    
    46.         originator.setState("状态2");    
    47.         System.out.println("改变后状态:"+originator.getState());    
    48.         originator.restoreMemento(caretaker.getMemento());    
    49.         System.out.println("恢复后状态:"+originator.getState());    
    50.     }    

           这个是什么啊,一份备忘录,一份状态备份。而我们要实现的对多个对象状态进行保存,所以大家也自己想想,该怎么实现,怎么下次再分享。

    备忘录模式的优点:

    1、  当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。

    2、  备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。

    备忘录模式的缺点:

    在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。

    使用场景:

    1、  需要回滚操作

    2、  恢复某不定时间前设定的状态

  • 相关阅读:
    Samba 4.0 RC3 发布
    SymmetricDS 3.1.7 发布,数据同步和复制
    Express.js 3.0 发布,Node.js 的高性能封装
    GIFLIB 5.0.1 发布,C语言的GIF处理库
    jQuery UI 1.9.1 发布
    SVN Access Manager 0.5.5.14 发布 SVN 管理工具
    DynamicReports 3.0.3 发布 Java 报表工具
    HttpComponents HttpClient 4.2.2 GA 发布
    AppCan 2.0 正式发布,推移动应用云服务
    Ruby 2.0 的新功能已经冻结
  • 原文地址:https://www.cnblogs.com/DoubleEggs/p/6030901.html
Copyright © 2011-2022 走看看