【设计模式】备忘录模式

背景:

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

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

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

 

什么是备忘录模式:

定义:

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

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

类图:

            

 

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

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

 

 

备忘录模式结构:

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

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

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

代码分析:

 

[java]  view plain copy
 print?在CODE上查看代码片派生到我的代码片
  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、  恢复某不定时间前设定的状态

转载于:https://www.cnblogs.com/DoubleEggs/p/6030901.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值