設計模式:備忘錄(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的代碼就能做到,職責明確是一種非常重要的是軟件工程思想。

  程序代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM