打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
备忘录模式——过关类游戏

一模式定义

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

 

二模式举例

1模式分析

我们借用过关类游戏来说明这一模式。


 

2备忘录模式静态类图


 

3代码示例(黑箱备忘录模式)

3.1创建备忘录窄接口一INarrowMemento

Java代码  
  1. package com.demo.memento;  
  2.   
  3. /** 
  4.  * 备忘录窄接口(不提供任何方法,外部对象不能访问备忘录对象内部信息) 
  5.  *  
  6.  * @author 
  7.  *  
  8.  */  
  9. public interface INarrowMemento {  
  10.   
  11. }  

3.2备忘录发起者一Hero

Java代码  
  1. package com.demo.originator;  
  2.   
  3. import java.util.Random;  
  4.   
  5. import com.demo.memento.INarrowMemento;  
  6.   
  7. /** 
  8.  * 挑战者 
  9.  *  
  10.  * @author 
  11.  *  
  12.  */  
  13. public class Hero {  
  14.     // 血液值  
  15.     private int blood;  
  16.     // 武力值  
  17.     private int sword;  
  18.   
  19.     // 随机数  
  20.     private final Random random = new Random();  
  21.   
  22.     // 构造方法初始化 内容  
  23.     public Hero() {  
  24.         this.blood = 100;  
  25.         this.sword = 100;  
  26.     }  
  27.   
  28.     // 创建备忘录保存内容  
  29.     public INarrowMemento createMemento() {  
  30.         System.out.println("创建备忘录...");  
  31.         return new Memento(this.blood, this.sword);  
  32.     }  
  33.   
  34.     // 恢复备忘录内容  
  35.     public void restoreFromMemento(INarrowMemento memento) {  
  36.         System.out.println("恢复备忘录中的状态...");  
  37.         if (memento != null) {  
  38.             Memento memento2 = (Memento) memento;  
  39.             this.blood = memento2.getBlood();  
  40.             this.sword = memento2.getSword();  
  41.         }  
  42.     }  
  43.   
  44.     /** 
  45.      * 挑战BOSS 
  46.      */  
  47.     public int koBoss() {  
  48.         // 当血液值<=0 时 挑战失败 假设战胜BOSS的概率为2%  
  49.         // 判断时候还有血液值  
  50.         if (this.blood <= 0 || this.sword <= 0) {  
  51.             System.out.println(this.toString());  
  52.             System.out.println("挑战BOSS失败!");  
  53.             return -1;  
  54.         } else {  
  55.             // 获得随机数  
  56.             double win = Math.random();  
  57.             if (win <= 0.02) {  
  58.                 System.out.println(this.toString());  
  59.                 System.out.println("恭喜你,挑战BOSS成功!");  
  60.                 return 1;  
  61.             } else {  
  62.                 System.out.println(this.toString());  
  63.                 System.out.println("继续攻击BOSS...");  
  64.                 // 随机数减少血液值和武力值 继续KO  
  65.                 int blood_sub = random.nextInt(10);  
  66.                 int sword_sub = random.nextInt(10);  
  67.                 this.blood -= blood_sub;  
  68.                 this.sword -= sword_sub;  
  69.                 return 0;  
  70.             }  
  71.         }  
  72.     }  
  73.   
  74.     @Override  
  75.     public String toString() {  
  76.         return "当前血液值:" + this.blood + " - 当前武力值:" + this.sword;  
  77.     }  
  78.   
  79.     /** 
  80.      * 备忘录(整个类都是私有的,只有发起者才能访问) 
  81.      *  
  82.      * @author 
  83.      *  
  84.      */  
  85.     private class Memento implements INarrowMemento {  
  86.         // 血液值  
  87.         private final int blood;  
  88.         // 武力值  
  89.         private final int sword;  
  90.   
  91.         // 构造方法初始化 内容  
  92.         private Memento(int blood, int sword) {  
  93.             this.blood = blood;  
  94.             this.sword = sword;  
  95.         }  
  96.   
  97.         private int getBlood() {  
  98.             return blood;  
  99.         }  
  100.   
  101.         private int getSword() {  
  102.             return sword;  
  103.         }  
  104.   
  105.     }  
  106.   
  107. }  

3.3备忘录管理者一Caretaker

Java代码  
  1. package com.demo.caretaker;  
  2.   
  3. import com.demo.memento.INarrowMemento;  
  4.   
  5. /** 
  6.  * 管理者 
  7.  *  
  8.  * @author 
  9.  *  
  10.  */  
  11. public class Caretaker {  
  12.     private INarrowMemento memento;  
  13.   
  14.     /** 
  15.      * 获得备忘录对象 
  16.      *  
  17.      * @return 
  18.      */  
  19.     public INarrowMemento getMemento() {  
  20.         return memento;  
  21.     }  
  22.   
  23.     /** 
  24.      * 保存备忘录对象 
  25.      *  
  26.      * @param memento 
  27.      */  
  28.     public void setMemento(INarrowMemento memento) {  
  29.         this.memento = memento;  
  30.     }  
  31.   
  32. }  

3.4让英雄挑战Boss一Client

Java代码  
  1. package com.demo;  
  2.   
  3. import com.demo.caretaker.Caretaker;  
  4. import com.demo.originator.Hero;  
  5.   
  6. /** 
  7.  * 客户端主应用程序 
  8.  *  
  9.  * @author 
  10.  *  
  11.  */  
  12. public class Client {  
  13.   
  14.     /** 
  15.      * @param args 
  16.      */  
  17.     public static void main(String[] args) {  
  18.         // 创建角色  
  19.         Hero hero = new Hero();  
  20.         // 创建管理者  
  21.         Caretaker caretaker = new Caretaker();  
  22.         // 保存挑战前的状态信息  
  23.         caretaker.setMemento(hero.createMemento());  
  24.         // 只有三次战胜BOSS的机会  
  25.         int cnt = 1;  
  26.         // 挑战BOSS结果  
  27.         int ko = -1;  
  28.         while (ko != 1 && cnt <= 3) {  
  29.             System.out  
  30.                     .println("=============== 第" + cnt + "次挑战 ==============");  
  31.             // 开始挑战BOSS  
  32.             ko = hero.koBoss();  
  33.             while (true) {  
  34.                 if (ko == -1) {  
  35.                     // 挑战失败 恢复到初始状态 累加挑战次数  
  36.                     hero.restoreFromMemento(caretaker.getMemento());  
  37.                     cnt += 1;  
  38.                     break;  
  39.                 } else if (ko == 0) {  
  40.                     // 继续挑战  
  41.                     ko = hero.koBoss();  
  42.                 } else if (ko == 1) {  
  43.                     // 挑战成功!  
  44.                     break;  
  45.                 }  
  46.             }  
  47.   
  48.         }  
  49.     }  
  50. }  

4运行结果

创建备忘录...

=============== 第1次挑战 ==============

当前血液值:100 - 当前武力值:100

继续攻击BOSS...

当前血液值:96 - 当前武力值:99

继续攻击BOSS...

当前血液值:90 - 当前武力值:98

继续攻击BOSS...

当前血液值:81 - 当前武力值:95

继续攻击BOSS...

当前血液值:78 - 当前武力值:93

继续攻击BOSS...

当前血液值:72 - 当前武力值:88

继续攻击BOSS...

当前血液值:64 - 当前武力值:85

继续攻击BOSS...

当前血液值:56 - 当前武力值:80

继续攻击BOSS...

当前血液值:49 - 当前武力值:73

继续攻击BOSS...

当前血液值:45 - 当前武力值:71

继续攻击BOSS...

当前血液值:37 - 当前武力值:68

继续攻击BOSS...

当前血液值:29 - 当前武力值:65

继续攻击BOSS...

当前血液值:20 - 当前武力值:59

继续攻击BOSS...

当前血液值:11 - 当前武力值:54

继续攻击BOSS...

当前血液值:9 - 当前武力值:52

继续攻击BOSS...

当前血液值:3 - 当前武力值:45

继续攻击BOSS...

当前血液值:-3 - 当前武力值:41

挑战BOSS失败!

恢复备忘录中的状态...

=============== 第2次挑战 ==============

当前血液值:100 - 当前武力值:100

继续攻击BOSS...

当前血液值:96 - 当前武力值:95

继续攻击BOSS...

当前血液值:96 - 当前武力值:91

继续攻击BOSS...

当前血液值:88 - 当前武力值:82

继续攻击BOSS...

当前血液值:79 - 当前武力值:79

继续攻击BOSS...

当前血液值:76 - 当前武力值:72

继续攻击BOSS...

当前血液值:73 - 当前武力值:70

继续攻击BOSS...

当前血液值:72 - 当前武力值:66

继续攻击BOSS...

当前血液值:72 - 当前武力值:61

继续攻击BOSS...

当前血液值:72 - 当前武力值:58

继续攻击BOSS...

当前血液值:72 - 当前武力值:52

继续攻击BOSS...

当前血液值:63 - 当前武力值:51

继续攻击BOSS...

当前血液值:62 - 当前武力值:50

继续攻击BOSS...

当前血液值:54 - 当前武力值:41

继续攻击BOSS...

当前血液值:50 - 当前武力值:39

继续攻击BOSS...

当前血液值:47 - 当前武力值:39

继续攻击BOSS...

当前血液值:43 - 当前武力值:38

继续攻击BOSS...

当前血液值:37 - 当前武力值:36

继续攻击BOSS...

当前血液值:34 - 当前武力值:35

继续攻击BOSS...

当前血液值:32 - 当前武力值:27

继续攻击BOSS...

当前血液值:28 - 当前武力值:22

继续攻击BOSS...

当前血液值:26 - 当前武力值:15

继续攻击BOSS...

当前血液值:24 - 当前武力值:11

继续攻击BOSS...

当前血液值:19 - 当前武力值:3

继续攻击BOSS...

当前血液值:10 - 当前武力值:-3

挑战BOSS失败!

恢复备忘录中的状态...

=============== 第3次挑战 ==============

当前血液值:100 - 当前武力值:100

继续攻击BOSS...

当前血液值:99 - 当前武力值:93

继续攻击BOSS...

当前血液值:98 - 当前武力值:84

继续攻击BOSS...

当前血液值:98 - 当前武力值:82

继续攻击BOSS...

当前血液值:95 - 当前武力值:76

继续攻击BOSS...

当前血液值:88 - 当前武力值:68

继续攻击BOSS...

当前血液值:81 - 当前武力值:64

继续攻击BOSS...

当前血液值:76 - 当前武力值:64

继续攻击BOSS...

当前血液值:67 - 当前武力值:64

恭喜你,挑战BOSS成功!

 

三该模式设计原则

1封装边界的保持

2双重接口实现,保证安全性。

 

四使用场合

1需要在某一时刻恢复一个对象先前的状态时。

2白箱备忘录模式,需要在外部保存对象某一时刻的状态,但如果用一个接口来让其他对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

3黑箱备忘录模式实现方式提供了双重接口访问机制,对发起者对象提供宽接口,而对发起者以外的对象提供窄接口,从而有效解决了封装性和安全性。

 

五静态类图

1白箱备忘录模式静态类图


 

2黑箱备忘录模式静态类图


 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
设计模式读书笔记-----备忘录模式
the pen is mightier than the sword 文胜于武
【C#设计模式-备忘录模式】
备忘录模式(Memento pattern)
备忘录模式(memento)解析例子
设计模式之备忘录(Memento Pattern)模式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服