【设计模式】—-(18)备忘录模式(行为型)

备忘录模式(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)不需要为支持迭代而破坏一个集合的封装性。

缺点:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值