博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】—-(18)备忘录模式(行为型)
阅读量:4103 次
发布时间:2019-05-25

本文共 4286 字,大约阅读时间需要 14 分钟。

备忘录模式(Token)

一、定义

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

二、适用场景

适合于功能比较复杂,但需要维护或记录属性历史的功能。

参与者:

      Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
  Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
  Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操作。

适用性:

1)必须保存一个对象在某一时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。

2)如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

效果:

1)保持封装边界

2)简化原发器

3)使用备忘录可能代价很高

4)定义窄接口和宽接口

5)维护备忘录的潜在代价

三、UML

四、代码

  1. /**
  2.  * 游戏自身(备忘录模式中的发起人,备份的是游戏的状态)
  3.  */
  4. public class Game {


  5.     /**
  6.      * 英雄状态属性
  7.      */
  8.     private HeroState hState;

  9.     /**
  10.      * 场景状态属性
  11.      */
  12.     private SceneState sState;

  13.     public HeroState gethState() {

  14.         return hState;
  15.     }

  16.     public void sethState(HeroState hState) {

  17.         this.hState = hState;
  18.     }

  19.     public SceneState getsState() {

  20.         return sState;
  21.     }

  22.     public void setsState(SceneState sState) {

  23.         this.sState = sState;
  24.     }

  25.     /**
  26.      * 备份游戏
  27.      */
  28.     public GameMemento createMemento(){

  29.         return new GameMemento(hState,sState);
  30.     }
  31.     
  32.     /**
  33.      * 玩游戏
  34.      * @throws InterruptedException 
  35.      */
  36.     public void play(){

  37.         hState.setHP(0);
  38.         hState.setMP(0);
  39.         sState.setCoin(0);
  40.         sState.setWood(0);
  41.     }
  42.     
  43.     /**
  44.      * 游戏还原
  45.      */
  46.     public void restore(GameMemento memento){

  47.         this.hState = memento.gethState();
  48.         this.sState = memento.getsState();
  49.     }
  50. }
2、第二个文件要备份的状态实体:HeroState.java 

点击(此处)折叠或打开

  1. /**
  2.  * 游戏英雄人物状态实体 
  3.  */
  4. public class HeroState implements Cloneable{


  5.     /**
  6.      * 英雄生命值
  7.      */
  8.     private int HP;
  9.     
  10.     /**
  11.      * 英雄魔法值
  12.      */
  13.     private int MP;
  14.     
  15.     /**
  16.      * 状态保存时间
  17.      */
  18.     private Date stateDate;

  19.     public int getHP() {

  20.         return HP;
  21.     }

  22.     public void setHP(int hP) {

  23.         HP = hP;
  24.     }

  25.     public int getMP() {

  26.         return MP;
  27.     }

  28.     public void setMP(int mP) {

  29.         MP = mP;
  30.     }

  31.     public Date getStateDate() {

  32.         return stateDate;
  33.     }

  34.     public void setStateDate(Date stateDate) {

  35.         this.stateDate = stateDate;
  36.     }
  37.     
  38.     public HeroState clone(){

  39.         try {

  40.             return (HeroState) super.clone();
  41.         } catch (CloneNotSupportedException e) {

  42.             // TODO Auto-generated catch block
  43.             e.printStackTrace();
  44.         }
  45.         return null;
  46.     }
  47. }
3、要备份的状态实体:SceneState.java 

点击(此处)折叠或打开

  1. /**
  2.  * 游戏场景状态实体 
  3.  */
  4. public class SceneState implements Cloneable{


  5.     /**
  6.      * 金币数量
  7.      */
  8.     private int coin;
  9.     
  10.     /**
  11.      * 木材数量
  12.      */
  13.     private int wood;
  14.     
  15.     /**
  16.      * 地图名称
  17.      */
  18.     private String mapName;

  19.     public int getCoin() {

  20.         return coin;
  21.     }

  22.     public void setCoin(int coin) {

  23.         this.coin = coin;
  24.     }

  25.     public int getWood() {

  26.         return wood;
  27.     }

  28.     public void setWood(int wood) {

  29.         this.wood = wood;
  30.     }

  31.     public String getMapName() {

  32.         return mapName;
  33.     }

  34.     public void setMapName(String mapName) {

  35.         this.mapName = mapName;
  36.     }
  37.     
  38.     public SceneState clone(){

  39.         try {

  40.             return (SceneState) super.clone();
  41.         } catch (CloneNotSupportedException e) {

  42.             // TODO Auto-generated catch block
  43.             e.printStackTrace();
  44.         }
  45.         return null;
  46.     }
  47. }
4、第四个文件备忘录角色:GameMemcento.java 

点击(此处)折叠或打开

  1. /**
  2.  * 游戏备忘录角色
  3.  */
  4. public class GameMemento{


  5.     /**
  6.      * 英雄状态
  7.      */
  8.     private HeroState hState;
  9.     
  10.     /**
  11.      * 场景状态
  12.      */
  13.     private SceneState sState;
  14.     
  15.     /**
  16.      * 构造方法
  17.      * @param hState
  18.      * @param sState
  19.      */
  20.     public GameMemento(HeroState hState,SceneState sState){

  21.         this.hState = hState.clone();
  22.         this.sState = sState.clone();
  23.     }

  24.     /**
  25.      * 获取备份状态
  26.      * @return
  27.      */
  28.     public HeroState gethState() {

  29.         return hState;
  30.     }

  31.     /**
  32.      * 获取备份状态
  33.      * @return
  34.      */
  35.     public SceneState getsState() {

  36.         return sState;
  37.     }
  38. }
5、第五个文件备忘录管理角色:Caretaker.java 

点击(此处)折叠或打开

  1. /**
  2.  * 备忘录管理器
  3.  */
  4. public class Caretaker {


  5.     /**
  6.      * 备忘录实体
  7.      */
  8.     private GameMemento memento;

  9.     public GameMemento getMemento() {

  10.         return memento;
  11.     }

  12.     public void setMemento(GameMemento memento) {

  13.         this.memento = memento;
  14.     }
  15. }
6、第六个文件:TestMain.java 

点击(此处)折叠或打开

  1. /**
  2.  * 测试Main方法
  3.  */
  4. public class TestMain {


  5.     public static void main(String [] args){

  6.         Game game = new Game();
  7.         HeroState hState = new HeroState();
  8.         hState.setHP(100);
  9.         hState.setMP(100);
  10.         SceneState sState = new SceneState();
  11.         sState.setCoin(1000);
  12.         sState.setWood(1000);
  13.         game.sethState(hState);
  14.         game.setsState(sState);
  15.         System.out.println("游戏状态备份开始");
  16.         GameMemento memento = game.createMemento();
  17.         Caretaker ct = new Caretaker();
  18.         ct.setMemento(memento);
  19.         System.out.println("游戏状态备份完成");
  20.         System.out.println("开始游戏,当前英雄生命值:" + game.gethState().getHP());
  21.         game.play();
  22.         System.out.println("游戏结束,当前英雄生命值:" + game.gethState().getHP());
  23.         System.out.println("游戏状态还原开始");
  24.         game.restore(ct.getMemento());
  25.         System.out.println("游戏状态还原结束");
  26.         System.out.println("当前英雄生命值:" + game.gethState().getHP());
  27.     }
  28. }

五、总结

备忘录模式

优点:

1)在同一个集合上可有多个状态一起工作

2)不需要为支持迭代而破坏一个集合的封装性。

缺点:

将对象状态备份会占用比较多的系统资源。

转载地址:http://reusi.baihongyu.com/

你可能感兴趣的文章
由一道bilibili面试题看Promise异步执行机制
查看>>
讲下 V8 sort 的大概思路,并手写一个 sort 的实现
查看>>
一道腾讯手写题,如何判断 url 中只包含 qq.com
查看>>
实现颜色转换 ‘rgb(255, 255, 255)‘ -> ‘#FFFFFF‘ 的多种思路
查看>>
es6 及 es6+ 的能力集,你最常用的,这其中最有用的,都解决了什么问题
查看>>
var、let、const 的本质区别是什么
查看>>
监听一个变量的变化,需要怎么做
查看>>
Promise.prototype.finally 的作用,如何自己实现 Promise.prototype.finally
查看>>
一文走进 HTTP 与 TCP 协议,它们的区别与联系
查看>>
http header怎么判断协议是不是websocket
查看>>
为什么说HTTPS比HTTP安全呢
查看>>
HTTP/2对比HTTP/1.1,特性是什么?是如何解决队头阻塞与压缩头部的?
查看>>
说一下 HTTP/3 新特性,为什么选择使用 UDP 协议?
查看>>
如果让你去实现一个 CSRF 攻击你会怎么做?
查看>>
Sqlite3递归查询,分页查询
查看>>
C# 图形编程 for RadioButton group ,checked & find
查看>>
Sqlite删除所有表的数据 C#实现
查看>>
C#使用WebService和Session
查看>>
如何学习新技术?
查看>>
Myeclipse使用常见问题汇总
查看>>