zoukankan      html  css  js  c++  java
  • 设计模式:备忘录(Memento)模式

    设计模式:备忘录(Memento)模式

    一、前言

      备忘录模式用于保存和恢复对象的状态,相信大家看过我前面的拙作就会想到原型模式也能保存一个对象在某一个时刻的状态,那么两者有何不同的呢?原型模式保存的是当前对象的所有状态信息,恢复的时候会生成与保存的对象完全相同的另外一个实例;而备忘录模式保存的是我们关心的在恢复时需要的对象的部分状态信息,相当于快照。备忘录模式大家肯定都见过,比如在玩游戏的时候有一个保存当前闯关的状态的功能,会对当前用户所处的状态进行保存,当用户闯关失败或者需要从快照的地方开始的时候,就能读取当时保存的状态完整地恢复到当时的环境,这一点和VMware上面的快照功能很类似。

    二、代码

      Memento类:

     1 package zyr.dp.memento;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 public class Memento {
     7     
     8     private int menoy;
     9     private ArrayList fruits;
    10 
    11     //窄接口,访问部分信息
    12     public int getMenoy(){
    13         return menoy;
    14     }
    15     
    16     //宽接口,本包之内皆可访问
    17     Memento(int menoy){
    18         this.menoy=menoy;
    19         fruits=new ArrayList();//每次调用的时候重新生成,很重要
    20     }
    21     //宽接口,本包之内皆可访问
    22     List getFruits(){
    23         return (List) fruits.clone();
    24     }
    25     //宽接口,本包之内皆可访问
    26     void  addFruits(String fruit){
    27         fruits.add(fruit);
    28     }
    29 
    30 }
    Gamer 类:
     1 package zyr.dp.memento;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 import java.util.Random;
     7 
     8 public class Gamer {
     9 
    10     private static  String[] FruitsSame={"香蕉","苹果","橘子","柚子"};
    11     
    12     private int menoy;
    13     private List fruits=new ArrayList();
    14     private  Random random=new Random();
    15     
    16     public int getMenoy(){
    17         return menoy;
    18     }
    19     
    20     public Gamer(int menoy){
    21         this.menoy=menoy;
    22     }
    23     
    24     public void bet(){
    25         int next=random.nextInt(6)+1;
    26         if(next==1){
    27             menoy+=100;
    28             System.out.println("金钱增加了100,当前金钱为:"+menoy);
    29         }else if(next==2){
    30             menoy/=2;
    31             System.out.println("金钱减少了一半,当前金钱为:"+menoy);
    32         }else if(next==6){
    33             String f=getFruit();
    34             fruits.add(f);
    35             System.out.println("获得了水果:"+f+",当前金钱为:"+menoy);
    36         }else {
    37             System.out.println("金钱没有发生改变,当前金钱为:"+menoy);
    38         }
    39     }
    40     
    41     private String getFruit() {
    42 
    43         String prefix="";
    44         if(random.nextBoolean()){
    45             prefix="好吃的";
    46         }
    47         return prefix+FruitsSame[random.nextInt(FruitsSame.length)];
    48         
    49     }
    50     
    51     public Memento createMemento(){
    52         Memento m=new Memento(menoy);
    53         Iterator it=fruits.iterator();
    54         while(it.hasNext()){
    55             String fruit=(String)it.next();
    56             if(fruit.startsWith("好吃的")){
    57                 m.addFruits(fruit);
    58             }
    59         }
    60         return m;
    61     }
    62     
    63     public  void restoreMemento(Memento memento){
    64         this.menoy=memento.getMenoy();
    65         this.fruits=memento.getFruits();
    66     }
    67     
    68     public String toString(){
    69         return "Menoy:"+menoy+" ,Fruits:"+fruits;
    70     }
    71     
    72 }

     Main类:

     1 package zyr.dp.test;
     2 
     3 import zyr.dp.memento.Gamer;
     4 import zyr.dp.memento.Memento;
     5 
     6 public class Main {
     7 
     8     public static void main(String[] args) {
     9         Gamer gamer=new Gamer(100);
    10         Memento memento=gamer.createMemento();
    11         for(int i=0;i<100;i++){
    12             System.out.println("当前状态:"+i);
    13             System.out.println("当前金额:"+gamer.getMenoy());
    14             gamer.bet();
    15             if(gamer.getMenoy()<memento.getMenoy()/2){
    16                 System.out.println("金钱过少,恢复到以前的状态:");
    17                 gamer.restoreMemento(memento);
    18                 System.out.println("此时状态为:"+gamer);
    19             }else if(gamer.getMenoy()>memento.getMenoy()){
    20                 System.out.println("金钱增多,保存当前状态:");
    21                 memento=gamer.createMemento();
    22                 System.out.println("此时状态为:"+gamer);
    23             }
    24             try {
    25                 Thread.sleep(500);
    26             } catch (InterruptedException e) {
    27                 e.printStackTrace();
    28             }
    29         }
    30 
    31     }
    32 
    33 }

     运行结果:

    当前状态:0
    当前金额:100
    金钱没有发生改变,当前金钱为:100
    当前状态:1
    当前金额:100
    金钱增加了100,当前金钱为:200
    金钱增多,保存当前状态:
    此时状态为:Menoy:200 ,Fruits:[]
    当前状态:2
    当前金额:200
    金钱增加了100,当前金钱为:300
    金钱增多,保存当前状态:
    此时状态为:Menoy:300 ,Fruits:[]
    当前状态:3
    当前金额:300
    金钱减少了一半,当前金钱为:150
    当前状态:4
    当前金额:150
    金钱减少了一半,当前金钱为:75
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:300 ,Fruits:[]
    当前状态:5
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:6
    当前金额:300
    金钱增加了100,当前金钱为:400
    金钱增多,保存当前状态:
    此时状态为:Menoy:400 ,Fruits:[]
    当前状态:7
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:8
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:9
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:10
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:11
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:12
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:13
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:14
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:15
    当前金额:300
    金钱增加了100,当前金钱为:400
    当前状态:16
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:17
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:18
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:19
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:20
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:21
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:22
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:23
    当前金额:200
    获得了水果:橘子,当前金钱为:200
    当前状态:24
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:25
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:26
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:27
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:28
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:29
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:30
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:31
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:32
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:33
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:34
    当前金额:300
    获得了水果:橘子,当前金钱为:300
    当前状态:35
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:36
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:37
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:38
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:39
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:40
    当前金额:300
    金钱减少了一半,当前金钱为:150
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[]
    当前状态:41
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:42
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:43
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:44
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:45
    当前金额:200
    金钱减少了一半,当前金钱为:100
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[]
    当前状态:46
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:47
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:48
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:49
    当前金额:400
    获得了水果:香蕉,当前金钱为:400
    当前状态:50
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:51
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:52
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:53
    当前金额:300
    金钱减少了一半,当前金钱为:150
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[]
    当前状态:54
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:55
    当前金额:200
    获得了水果:好吃的柚子,当前金钱为:200
    当前状态:56
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:57
    当前金额:200
    获得了水果:好吃的香蕉,当前金钱为:200
    当前状态:58
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:59
    当前金额:200
    获得了水果:香蕉,当前金钱为:200
    当前状态:60
    当前金额:200
    获得了水果:苹果,当前金钱为:200
    当前状态:61
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:62
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:63
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:64
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:65
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:66
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:67
    当前金额:300
    金钱减少了一半,当前金钱为:150
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[]
    当前状态:68
    当前金额:400
    金钱增加了100,当前金钱为:500
    金钱增多,保存当前状态:
    此时状态为:Menoy:500 ,Fruits:[]
    当前状态:69
    当前金额:500
    金钱增加了100,当前金钱为:600
    金钱增多,保存当前状态:
    此时状态为:Menoy:600 ,Fruits:[]
    当前状态:70
    当前金额:600
    金钱没有发生改变,当前金钱为:600
    当前状态:71
    当前金额:600
    金钱没有发生改变,当前金钱为:600
    当前状态:72
    当前金额:600
    金钱没有发生改变,当前金钱为:600
    当前状态:73
    当前金额:600
    金钱增加了100,当前金钱为:700
    金钱增多,保存当前状态:
    此时状态为:Menoy:700 ,Fruits:[]
    当前状态:74
    当前金额:700
    金钱增加了100,当前金钱为:800
    金钱增多,保存当前状态:
    此时状态为:Menoy:800 ,Fruits:[]
    当前状态:75
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:76
    当前金额:800
    获得了水果:好吃的柚子,当前金钱为:800
    当前状态:77
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:78
    当前金额:800
    金钱减少了一半,当前金钱为:400
    当前状态:79
    当前金额:400
    金钱减少了一半,当前金钱为:200
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:800 ,Fruits:[]
    当前状态:80
    当前金额:800
    获得了水果:好吃的苹果,当前金钱为:800
    当前状态:81
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:82
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:83
    当前金额:800
    获得了水果:好吃的柚子,当前金钱为:800
    当前状态:84
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:85
    当前金额:800
    金钱没有发生改变,当前金钱为:800
    当前状态:86
    当前金额:800
    金钱增加了100,当前金钱为:900
    金钱增多,保存当前状态:
    此时状态为:Menoy:900 ,Fruits:[好吃的苹果, 好吃的柚子]
    当前状态:87
    当前金额:900
    金钱减少了一半,当前金钱为:450
    当前状态:88
    当前金额:450
    金钱增加了100,当前金钱为:550
    当前状态:89
    当前金额:550
    金钱增加了100,当前金钱为:650
    当前状态:90
    当前金额:650
    金钱增加了100,当前金钱为:750
    当前状态:91
    当前金额:750
    获得了水果:柚子,当前金钱为:750
    当前状态:92
    当前金额:750
    金钱没有发生改变,当前金钱为:750
    当前状态:93
    当前金额:750
    金钱增加了100,当前金钱为:850
    当前状态:94
    当前金额:850
    金钱减少了一半,当前金钱为:425
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:900 ,Fruits:[好吃的苹果, 好吃的柚子]
    当前状态:95
    当前金额:900
    获得了水果:好吃的橘子,当前金钱为:900
    当前状态:96
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:97
    当前金额:900
    金钱增加了100,当前金钱为:1000
    金钱增多,保存当前状态:
    此时状态为:Menoy:1000 ,Fruits:[好吃的苹果, 好吃的柚子, 好吃的橘子]
    当前状态:98
    当前金额:1000
    金钱减少了一半,当前金钱为:500
    当前状态:99
    当前金额:500
    金钱减少了一半,当前金钱为:250
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1000 ,Fruits:[好吃的苹果, 好吃的柚子, 好吃的橘子]
    运行结果

        本程序的功能是根据循环次数随机的生成1~6这6个数字,如果数字是1,则金钱加一百,如果是二,则金钱减半,如果是6,则随机生成水果,水果分为好吃的和不好吃的,在保存的时候只保存好吃的水果,恢复的时候就只有好吃的水果了。当金钱少于当前备忘录中金钱的一半的时候就要恢复到备忘录的状态;当金钱大于备忘录的状态的时候就要备份当前的状态,备份的时候只备份好的水果以及当前金额,这就是游戏的功能,可以看到运行的结果的正确性。

      这里有几点要注意:

       2.1、窄接口和宽接口

       在代码中我已经标注出了窄接口和宽接口,如何定义这两种接口还要看这两种接口前面的修饰符,如果是默认的(只有本包的类可以使用),并且这些接口结合到一起可以完全的将本类的信息显示出来,那么就是宽接口;只能在本包之中使用,如果修饰符是public的接口,并且只能表示本类一部分信息,因为是public可以在其他包中使用的,就是窄接口,只能查看部分信息,因此是窄的。如下图所示,对于Main类所在的包,只能使用其他两个类中声明为public的字段和方法,因此在Main中只能使用窄接口来完成一定信息的读取getMenoy()。这只是一个概念,强调的是类、字段、方法的可见性。

     

        2.2、可见性

       同时我们也知道,public修饰的字段和方法在任何包中都可以使用,private修饰的字段和方法只能在本类之中使用,protected修饰的方法可以在本包之中以及该类的子类(可以在其他包)中使用,默认的没有任何修饰的可以在本包之中使用。这就是四种修饰关键字的可见性。在编程的时候我们一定要考虑这些问题,不然就会导致我们不想看到的字段、方法、类被误用的结果。

      2.3、将备份内容存盘并且读取

     Memento类:

     1 package zyr.dp.serializable;
     2 
     3 import java.io.Serializable;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class Memento implements Serializable {
     8     
     9     private static final long serialVersionUID = 8497203738547925495L;
    10     
    11     private int menoy;
    12     private ArrayList fruits;
    13 
    14     //窄接口,访问部分信息
    15     public int getMenoy(){
    16         return menoy;
    17     }
    18     
    19     //宽接口,本包之内皆可访问
    20     Memento(int menoy){
    21         this.menoy=menoy;
    22         fruits=new ArrayList();//每次调用的时候重新生成,很重要
    23     }
    24     //宽接口,本包之内皆可访问
    25     List getFruits(){
    26         return (List) fruits.clone();
    27     }
    28     //宽接口,本包之内皆可访问
    29     void  addFruits(String fruit){
    30         fruits.add(fruit);
    31     }
    32 
    33 }

     Gamer类:

     1 package zyr.dp.serializable;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 import java.util.Random;
     7 
     8 public class Gamer {
     9 
    10     private static  String[] FruitsSame={"香蕉","苹果","橘子","柚子"};
    11     
    12     private int menoy;
    13     private List fruits=new ArrayList();
    14     private  Random random=new Random();
    15     
    16     public int getMenoy(){
    17         return menoy;
    18     }
    19     
    20     public Gamer(int menoy){
    21         this.menoy=menoy;
    22     }
    23     
    24     public void bet(){
    25         int next=random.nextInt(6)+1;
    26         if(next==1){
    27             menoy+=100;
    28             System.out.println("金钱增加了100,当前金钱为:"+menoy);
    29         }else if(next==2){
    30             menoy/=2;
    31             System.out.println("金钱减少了一半,当前金钱为:"+menoy);
    32         }else if(next==6){
    33             String f=getFruit();
    34             fruits.add(f);
    35             System.out.println("获得了水果:"+f+",当前金钱为:"+menoy);
    36         }else {
    37             System.out.println("金钱没有发生改变,当前金钱为:"+menoy);
    38         }
    39     }
    40     
    41     private String getFruit() {
    42 
    43         String prefix="";
    44         if(random.nextBoolean()){
    45             prefix="好吃的";
    46         }
    47         return prefix+FruitsSame[random.nextInt(FruitsSame.length)];
    48         
    49     }
    50     
    51     public Memento createMemento(){
    52         Memento m=new Memento(menoy);
    53         Iterator it=fruits.iterator();
    54         while(it.hasNext()){
    55             String fruit=(String)it.next();
    56             if(fruit.startsWith("好吃的")){
    57                 m.addFruits(fruit);
    58             }
    59         }
    60         return m;
    61     }
    62     
    63     public  void restoreMemento(Memento memento){
    64         this.menoy=memento.getMenoy();
    65         this.fruits=memento.getFruits();
    66     }
    67     
    68     public String toString(){
    69         return "Menoy:"+menoy+" ,Fruits:"+fruits;
    70     }
    71     
    72 }

     SerializableMain类:

     1 package zyr.dp.test;
     2 
     3 import java.io.*;
     4 
     5 import zyr.dp.serializable.Gamer;
     6 import zyr.dp.serializable.Memento;
     7 
     8 
     9 public class SerializableMain {
    10 
    11     private static String filename="game.dat";
    12     public static void main(String[] args) {
    13         Gamer gamer=new Gamer(100);
    14         Memento memento=loadMemento();
    15         
    16         if(memento==null){
    17              memento=gamer.createMemento();
    18         }else{
    19             System.out.println("从上次保存处开始...");
    20             gamer.restoreMemento(memento);
    21         }
    22         
    23         for(int i=0;i<100;i++){
    24             System.out.println("当前状态:"+i);
    25             System.out.println("当前金额:"+gamer.getMenoy());
    26             gamer.bet();
    27             if(gamer.getMenoy()<memento.getMenoy()/2){
    28                 System.out.println("金钱过少,恢复到以前的状态:");
    29                 gamer.restoreMemento(memento);
    30                 System.out.println("此时状态为:"+gamer);
    31             }else if(gamer.getMenoy()>memento.getMenoy()){
    32                 System.out.println("金钱增多,保存当前状态:");
    33                 memento=gamer.createMemento();
    34                 saveMemento(memento);
    35                 System.out.println("此时状态为:"+gamer);
    36             }
    37             try {
    38                 Thread.sleep(500);
    39             } catch (InterruptedException e) {
    40                 e.printStackTrace();
    41             }
    42         }
    43 
    44     }
    45     private static void saveMemento(Memento memento) {
    46         try {
    47             ObjectOutput o=new ObjectOutputStream(new FileOutputStream(filename));
    48             o.writeObject(memento);
    49             o.close();
    50         } catch (FileNotFoundException e) {
    51             e.printStackTrace();
    52         } catch (IOException e) {
    53             e.printStackTrace();
    54         }
    55     }
    56     private static Memento loadMemento() {
    57         Memento memento=null;
    58         ObjectInput in;
    59         try {
    60             in = new ObjectInputStream(new FileInputStream(filename));
    61             memento=(Memento)in.readObject();
    62             in.close();
    63         } catch (FileNotFoundException e) {
    64             System.out.println(e.toString());
    65         } catch (IOException e) {
    66             e.printStackTrace();
    67         } catch (ClassNotFoundException e) {
    68             e.printStackTrace();
    69         }
    70         return memento;
    71     }
    72 
    73 }

    运行结果:

    初次运行:

    java.io.FileNotFoundException: game.dat (系统找不到指定的文件。)
    当前状态:0
    当前金额:100
    获得了水果:好吃的苹果,当前金钱为:100
    当前状态:1
    当前金额:100
    金钱没有发生改变,当前金钱为:100
    当前状态:2
    当前金额:100
    金钱没有发生改变,当前金钱为:100
    当前状态:3
    当前金额:100
    金钱没有发生改变,当前金钱为:100
    当前状态:4
    当前金额:100
    获得了水果:苹果,当前金钱为:100
    当前状态:5
    当前金额:100
    金钱没有发生改变,当前金钱为:100
    当前状态:6
    当前金额:100
    金钱增加了100,当前金钱为:200
    金钱增多,保存当前状态:
    此时状态为:Menoy:200 ,Fruits:[好吃的苹果, 苹果]
    当前状态:7
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:8
    当前金额:200
    金钱增加了100,当前金钱为:300
    金钱增多,保存当前状态:
    此时状态为:Menoy:300 ,Fruits:[好吃的苹果, 苹果]
    当前状态:9
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:10
    当前金额:300
    获得了水果:橘子,当前金钱为:300
    当前状态:11
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:12
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:13
    当前金额:300
    金钱增加了100,当前金钱为:400
    金钱增多,保存当前状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果, 苹果, 橘子]
    当前状态:14
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:15
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:16
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:17
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:18
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:19
    当前金额:200
    获得了水果:好吃的柚子,当前金钱为:200
    当前状态:20
    当前金额:200
    获得了水果:好吃的柚子,当前金钱为:200
    当前状态:21
    当前金额:200
    金钱减少了一半,当前金钱为:100
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果]
    当前状态:22
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:23
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:24
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:25
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:26
    当前金额:300
    金钱没有发生改变,当前金钱为:300
    当前状态:27
    当前金额:300
    金钱减少了一半,当前金钱为:150
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果]
    当前状态:28
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:29
    当前金额:400
    获得了水果:香蕉,当前金钱为:400
    当前状态:30
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:31
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:32
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:33
    当前金额:200
    获得了水果:柚子,当前金钱为:200
    当前状态:34
    当前金额:200
    金钱减少了一半,当前金钱为:100
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果]
    当前状态:35
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:36
    当前金额:400
    获得了水果:橘子,当前金钱为:400
    当前状态:37
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:38
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:39
    当前金额:200
    获得了水果:好吃的橘子,当前金钱为:200
    当前状态:40
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:41
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:42
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:43
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:44
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:45
    当前金额:200
    金钱增加了100,当前金钱为:300
    当前状态:46
    当前金额:300
    金钱减少了一半,当前金钱为:150
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果]
    当前状态:47
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:48
    当前金额:400
    金钱减少了一半,当前金钱为:200
    当前状态:49
    当前金额:200
    获得了水果:柚子,当前金钱为:200
    当前状态:50
    当前金额:200
    金钱没有发生改变,当前金钱为:200
    当前状态:51
    当前金额:200
    金钱减少了一半,当前金钱为:100
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:400 ,Fruits:[好吃的苹果]
    当前状态:52
    当前金额:400
    获得了水果:香蕉,当前金钱为:400
    当前状态:53
    当前金额:400
    金钱没有发生改变,当前金钱为:400
    当前状态:54
    当前金额:400
    金钱增加了100,当前金钱为:500
    金钱增多,保存当前状态:
    此时状态为:Menoy:500 ,Fruits:[好吃的苹果, 香蕉]
    当前状态:55
    当前金额:500
    金钱减少了一半,当前金钱为:250
    当前状态:56
    当前金额:250
    获得了水果:好吃的苹果,当前金钱为:250
    当前状态:57
    当前金额:250
    金钱减少了一半,当前金钱为:125
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:500 ,Fruits:[好吃的苹果]
    当前状态:58
    当前金额:500
    金钱没有发生改变,当前金钱为:500
    当前状态:59
    当前金额:500
    获得了水果:柚子,当前金钱为:500
    当前状态:60
    当前金额:500
    金钱减少了一半,当前金钱为:250
    当前状态:61
    当前金额:250
    金钱没有发生改变,当前金钱为:250
    当前状态:62
    当前金额:250
    金钱增加了100,当前金钱为:350
    当前状态:63
    当前金额:350
    金钱没有发生改变,当前金钱为:350
    当前状态:64
    当前金额:350
    金钱减少了一半,当前金钱为:175
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:500 ,Fruits:[好吃的苹果]
    当前状态:65
    当前金额:500
    获得了水果:柚子,当前金钱为:500
    当前状态:66
    当前金额:500
    金钱增加了100,当前金钱为:600
    金钱增多,保存当前状态:
    此时状态为:Menoy:600 ,Fruits:[好吃的苹果, 柚子]
    当前状态:67
    当前金额:600
    金钱没有发生改变,当前金钱为:600
    当前状态:68
    当前金额:600
    金钱增加了100,当前金钱为:700
    金钱增多,保存当前状态:
    此时状态为:Menoy:700 ,Fruits:[好吃的苹果, 柚子]
    当前状态:69
    当前金额:700
    获得了水果:好吃的橘子,当前金钱为:700
    当前状态:70
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:71
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:72
    当前金额:700
    获得了水果:香蕉,当前金钱为:700
    当前状态:73
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:74
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:75
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:76
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:77
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:78
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:79
    当前金额:700
    金钱没有发生改变,当前金钱为:700
    当前状态:80
    当前金额:700
    金钱增加了100,当前金钱为:800
    金钱增多,保存当前状态:
    此时状态为:Menoy:800 ,Fruits:[好吃的苹果, 柚子, 好吃的橘子, 香蕉]
    当前状态:81
    当前金额:800
    金钱增加了100,当前金钱为:900
    金钱增多,保存当前状态:
    此时状态为:Menoy:900 ,Fruits:[好吃的苹果, 柚子, 好吃的橘子, 香蕉]
    当前状态:82
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:83
    当前金额:900
    获得了水果:柚子,当前金钱为:900
    当前状态:84
    当前金额:900
    金钱减少了一半,当前金钱为:450
    当前状态:85
    当前金额:450
    金钱没有发生改变,当前金钱为:450
    当前状态:86
    当前金额:450
    金钱增加了100,当前金钱为:550
    当前状态:87
    当前金额:550
    获得了水果:好吃的柚子,当前金钱为:550
    当前状态:88
    当前金额:550
    金钱没有发生改变,当前金钱为:550
    当前状态:89
    当前金额:550
    金钱没有发生改变,当前金钱为:550
    当前状态:90
    当前金额:550
    金钱没有发生改变,当前金钱为:550
    当前状态:91
    当前金额:550
    获得了水果:好吃的香蕉,当前金钱为:550
    当前状态:92
    当前金额:550
    金钱减少了一半,当前金钱为:275
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:900 ,Fruits:[好吃的苹果, 好吃的橘子]
    当前状态:93
    当前金额:900
    金钱增加了100,当前金钱为:1000
    金钱增多,保存当前状态:
    此时状态为:Menoy:1000 ,Fruits:[好吃的苹果, 好吃的橘子]
    当前状态:94
    当前金额:1000
    获得了水果:橘子,当前金钱为:1000
    当前状态:95
    当前金额:1000
    金钱减少了一半,当前金钱为:500
    当前状态:96
    当前金额:500
    金钱没有发生改变,当前金钱为:500
    当前状态:97
    当前金额:500
    金钱没有发生改变,当前金钱为:500
    当前状态:98
    当前金额:500
    获得了水果:柚子,当前金钱为:500
    当前状态:99
    当前金额:500
    获得了水果:柚子,当前金钱为:500
    View Code

     第二次运行:

    从上次保存处开始...
    当前状态:0
    当前金额:1000
    金钱没有发生改变,当前金钱为:1000
    当前状态:1
    当前金额:1000
    金钱增加了100,当前金钱为:1100
    金钱增多,保存当前状态:
    此时状态为:Menoy:1100 ,Fruits:[好吃的苹果, 好吃的橘子]
    当前状态:2
    当前金额:1100
    金钱增加了100,当前金钱为:1200
    金钱增多,保存当前状态:
    此时状态为:Menoy:1200 ,Fruits:[好吃的苹果, 好吃的橘子]
    当前状态:3
    当前金额:1200
    获得了水果:香蕉,当前金钱为:1200
    当前状态:4
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:5
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:6
    当前金额:1200
    获得了水果:好吃的橘子,当前金钱为:1200
    当前状态:7
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:8
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:9
    当前金额:1200
    获得了水果:好吃的苹果,当前金钱为:1200
    当前状态:10
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:11
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:12
    当前金额:1200
    获得了水果:好吃的橘子,当前金钱为:1200
    当前状态:13
    当前金额:1200
    获得了水果:好吃的柚子,当前金钱为:1200
    当前状态:14
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:15
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:16
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:17
    当前金额:1200
    获得了水果:苹果,当前金钱为:1200
    当前状态:18
    当前金额:1200
    金钱没有发生改变,当前金钱为:1200
    当前状态:19
    当前金额:1200
    金钱增加了100,当前金钱为:1300
    金钱增多,保存当前状态:
    此时状态为:Menoy:1300 ,Fruits:[好吃的苹果, 好吃的橘子, 香蕉, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子, 苹果]
    当前状态:20
    当前金额:1300
    金钱没有发生改变,当前金钱为:1300
    当前状态:21
    当前金额:1300
    金钱减少了一半,当前金钱为:650
    当前状态:22
    当前金额:650
    获得了水果:好吃的苹果,当前金钱为:650
    当前状态:23
    当前金额:650
    金钱增加了100,当前金钱为:750
    当前状态:24
    当前金额:750
    金钱减少了一半,当前金钱为:375
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1300 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:25
    当前金额:1300
    金钱没有发生改变,当前金钱为:1300
    当前状态:26
    当前金额:1300
    金钱增加了100,当前金钱为:1400
    金钱增多,保存当前状态:
    此时状态为:Menoy:1400 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:27
    当前金额:1400
    金钱没有发生改变,当前金钱为:1400
    当前状态:28
    当前金额:1400
    金钱没有发生改变,当前金钱为:1400
    当前状态:29
    当前金额:1400
    金钱增加了100,当前金钱为:1500
    金钱增多,保存当前状态:
    此时状态为:Menoy:1500 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:30
    当前金额:1500
    金钱增加了100,当前金钱为:1600
    金钱增多,保存当前状态:
    此时状态为:Menoy:1600 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:31
    当前金额:1600
    金钱没有发生改变,当前金钱为:1600
    当前状态:32
    当前金额:1600
    金钱没有发生改变,当前金钱为:1600
    当前状态:33
    当前金额:1600
    金钱没有发生改变,当前金钱为:1600
    当前状态:34
    当前金额:1600
    金钱增加了100,当前金钱为:1700
    金钱增多,保存当前状态:
    此时状态为:Menoy:1700 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:35
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:36
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:37
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:38
    当前金额:1700
    金钱减少了一半,当前金钱为:850
    当前状态:39
    当前金额:850
    金钱没有发生改变,当前金钱为:850
    当前状态:40
    当前金额:850
    金钱没有发生改变,当前金钱为:850
    当前状态:41
    当前金额:850
    金钱没有发生改变,当前金钱为:850
    当前状态:42
    当前金额:850
    金钱没有发生改变,当前金钱为:850
    当前状态:43
    当前金额:850
    金钱增加了100,当前金钱为:950
    当前状态:44
    当前金额:950
    金钱减少了一半,当前金钱为:475
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1700 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:45
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:46
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:47
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:48
    当前金额:1700
    金钱没有发生改变,当前金钱为:1700
    当前状态:49
    当前金额:1700
    金钱增加了100,当前金钱为:1800
    金钱增多,保存当前状态:
    此时状态为:Menoy:1800 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:50
    当前金额:1800
    金钱减少了一半,当前金钱为:900
    当前状态:51
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:52
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:53
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:54
    当前金额:900
    获得了水果:好吃的柚子,当前金钱为:900
    当前状态:55
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:56
    当前金额:900
    金钱没有发生改变,当前金钱为:900
    当前状态:57
    当前金额:900
    获得了水果:好吃的柚子,当前金钱为:900
    当前状态:58
    当前金额:900
    金钱减少了一半,当前金钱为:450
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1800 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:59
    当前金额:1800
    金钱增加了100,当前金钱为:1900
    金钱增多,保存当前状态:
    此时状态为:Menoy:1900 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:60
    当前金额:1900
    金钱没有发生改变,当前金钱为:1900
    当前状态:61
    当前金额:1900
    金钱没有发生改变,当前金钱为:1900
    当前状态:62
    当前金额:1900
    金钱没有发生改变,当前金钱为:1900
    当前状态:63
    当前金额:1900
    获得了水果:好吃的柚子,当前金钱为:1900
    当前状态:64
    当前金额:1900
    金钱没有发生改变,当前金钱为:1900
    当前状态:65
    当前金额:1900
    金钱减少了一半,当前金钱为:950
    当前状态:66
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:67
    当前金额:950
    获得了水果:柚子,当前金钱为:950
    当前状态:68
    当前金额:950
    金钱减少了一半,当前金钱为:475
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1900 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:69
    当前金额:1900
    金钱减少了一半,当前金钱为:950
    当前状态:70
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:71
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:72
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:73
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:74
    当前金额:950
    金钱增加了100,当前金钱为:1050
    当前状态:75
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:76
    当前金额:1050
    获得了水果:好吃的香蕉,当前金钱为:1050
    当前状态:77
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:78
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:79
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:80
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:81
    当前金额:1050
    获得了水果:柚子,当前金钱为:1050
    当前状态:82
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:83
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:84
    当前金额:1050
    金钱增加了100,当前金钱为:1150
    当前状态:85
    当前金额:1150
    金钱没有发生改变,当前金钱为:1150
    当前状态:86
    当前金额:1150
    金钱增加了100,当前金钱为:1250
    当前状态:87
    当前金额:1250
    金钱减少了一半,当前金钱为:625
    金钱过少,恢复到以前的状态:
    此时状态为:Menoy:1900 ,Fruits:[好吃的苹果, 好吃的橘子, 好吃的橘子, 好吃的苹果, 好吃的橘子, 好吃的柚子]
    当前状态:88
    当前金额:1900
    获得了水果:苹果,当前金钱为:1900
    当前状态:89
    当前金额:1900
    金钱减少了一半,当前金钱为:950
    当前状态:90
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:91
    当前金额:950
    获得了水果:好吃的橘子,当前金钱为:950
    当前状态:92
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:93
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:94
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:95
    当前金额:950
    金钱没有发生改变,当前金钱为:950
    当前状态:96
    当前金额:950
    获得了水果:好吃的橘子,当前金钱为:950
    当前状态:97
    当前金额:950
    金钱增加了100,当前金钱为:1050
    当前状态:98
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    当前状态:99
    当前金额:1050
    金钱没有发生改变,当前金钱为:1050
    第二次运行

      可以看到保存和读取成功。

    三、总结

      备忘录模式也是一种比较常用的模式用来保存对象的部分用于恢复的信息,和原型模式有着本质的区别,广泛运用在快照功能之中,另外我们知道了宽接口和窄接口,这里的接口就是指的方法,没有其他意思,以及类的可见性。同样的使用备忘录模式可以使得程序可以组件化,比如打算多次撤销当前的状态,以及不仅可以撤销而且可以将当前的状态保存到文件之中的时候,我们不需要修改Gamer的代码就能做到,职责明确是一种非常重要的是软件工程思想。

      程序代码

  • 相关阅读:
    一个很吊的swing循环生成窗口。
    hbase操作的问题
    hadoop+hbase
    linux故障救援
    管道命令xargs
    hadoop浅尝 hadoop与hbase交互
    linux源代码阅读笔记 free_page_tables()分析
    词法分析器flex的使用
    每天一个Linux命令(1): find
    梯度下降
  • 原文地址:https://www.cnblogs.com/zyrblog/p/9249660.html
Copyright © 2011-2022 走看看