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、  恢复某不定时间前设定的状态

  • 相关阅读:
    PAT乙级1002. 写出这个数 (20)
    PAT乙级1001. 害死人不偿命的(3n+1)猜想 (15)
    HDU 4520 小Q系列故事——最佳裁判
    POJ 3414 Pots(BFS)
    POJ 1118 Lining Up
    POJ 2484 A Funny Game
    POJ 2231 Moo Volume
    HDU 5718 Oracle(高精度)
    FZU 1502 Letter Deletion(DP)
    HDU 1564 Play a game
  • 原文地址:https://www.cnblogs.com/DoubleEggs/p/6030901.html
Copyright © 2011-2022 走看看