北风设计模式课程---备忘录(Memento)模式

一、总结

一句话总结:

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

1、备忘录模式和原型模式的共同点?

都是保存一个对象在某一个时刻的状态

2、备忘录模式和原型模式的区别?

创建模式 >< 行为模式:备忘录模式是行为模式
多份对象 >< 一份对象:原型模式是多份对象,而备忘录模式只是操作一个实例

原型模式保存的是当前对象的所有状态信息,恢复的时候会生成与保存的对象完全相同的另外一个实例;
而备忘录模式保存的是我们关心的在恢复时需要的对象的部分状态信息,相当于快照。

3、职责明确这一思想在设计模式中有哪些体现?

比如备忘录模式的管理者角色

4、备忘录模式中 原生者角色 最核心的两个方法是什么?

创建备份方法和恢复备份方法
public Memento createMemento(){
Memento m=new Memento(menoy);
Iterator it=fruits.iterator();
while(it.hasNext()){
String fruit=(String)it.next();
if(fruit.startsWith("好吃的")){
m.addFruits(fruit);
}
}
return m;
} public void restoreMemento(Memento memento){
this.menoy=memento.getMenoy();
this.fruits=memento.getFruits();
}

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

转自或参考:设计模式:备忘录(Memento)模式
https://www.cnblogs.com/zyrblog/p/9249660.html

一、前言

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

二、代码

  Memento类:

 package zyr.dp.memento;

 import java.util.ArrayList;
import java.util.List; public class Memento { private int menoy;
private ArrayList fruits; //窄接口,访问部分信息
public int getMenoy(){
return menoy;
} //宽接口,本包之内皆可访问
Memento(int menoy){
this.menoy=menoy;
fruits=new ArrayList();//每次调用的时候重新生成,很重要
}
//宽接口,本包之内皆可访问
List getFruits(){
return (List) fruits.clone();
}
//宽接口,本包之内皆可访问
void addFruits(String fruit){
fruits.add(fruit);
} }
Gamer 类:
 package zyr.dp.memento;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random; public class Gamer { private static String[] FruitsSame={"香蕉","苹果","橘子","柚子"}; private int menoy;
private List fruits=new ArrayList();
private Random random=new Random(); public int getMenoy(){
return menoy;
} public Gamer(int menoy){
this.menoy=menoy;
} public void bet(){
int next=random.nextInt(6)+1;
if(next==1){
menoy+=100;
System.out.println("金钱增加了100,当前金钱为:"+menoy);
}else if(next==2){
menoy/=2;
System.out.println("金钱减少了一半,当前金钱为:"+menoy);
}else if(next==6){
String f=getFruit();
fruits.add(f);
System.out.println("获得了水果:"+f+",当前金钱为:"+menoy);
}else {
System.out.println("金钱没有发生改变,当前金钱为:"+menoy);
}
} private String getFruit() { String prefix="";
if(random.nextBoolean()){
prefix="好吃的";
}
return prefix+FruitsSame[random.nextInt(FruitsSame.length)]; } public Memento createMemento(){
Memento m=new Memento(menoy);
Iterator it=fruits.iterator();
while(it.hasNext()){
String fruit=(String)it.next();
if(fruit.startsWith("好吃的")){
m.addFruits(fruit);
}
}
return m;
} public void restoreMemento(Memento memento){
this.menoy=memento.getMenoy();
this.fruits=memento.getFruits();
} public String toString(){
return "Menoy:"+menoy+" ,Fruits:"+fruits;
} }

 Main类:

 package zyr.dp.test;

 import zyr.dp.memento.Gamer;
import zyr.dp.memento.Memento; public class Main { public static void main(String[] args) {
Gamer gamer=new Gamer(100);
Memento memento=gamer.createMemento();
for(int i=0;i<100;i++){
System.out.println("当前状态:"+i);
System.out.println("当前金额:"+gamer.getMenoy());
gamer.bet();
if(gamer.getMenoy()<memento.getMenoy()/2){
System.out.println("金钱过少,恢复到以前的状态:");
gamer.restoreMemento(memento);
System.out.println("此时状态为:"+gamer);
}else if(gamer.getMenoy()>memento.getMenoy()){
System.out.println("金钱增多,保存当前状态:");
memento=gamer.createMemento();
System.out.println("此时状态为:"+gamer);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} } }

 运行结果:

当前状态: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类:

 package zyr.dp.serializable;

 import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; public class Memento implements Serializable {

private static final long serialVersionUID = 8497203738547925495L; private int menoy;
private ArrayList fruits; //窄接口,访问部分信息
public int getMenoy(){
return menoy;
} //宽接口,本包之内皆可访问
Memento(int menoy){
this.menoy=menoy;
fruits=new ArrayList();//每次调用的时候重新生成,很重要
}
//宽接口,本包之内皆可访问
List getFruits(){
return (List) fruits.clone();
}
//宽接口,本包之内皆可访问
void addFruits(String fruit){
fruits.add(fruit);
} }

 Gamer类:

 package zyr.dp.serializable;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random; public class Gamer { private static String[] FruitsSame={"香蕉","苹果","橘子","柚子"}; private int menoy;
private List fruits=new ArrayList();
private Random random=new Random(); public int getMenoy(){
return menoy;
} public Gamer(int menoy){
this.menoy=menoy;
} public void bet(){
int next=random.nextInt(6)+1;
if(next==1){
menoy+=100;
System.out.println("金钱增加了100,当前金钱为:"+menoy);
}else if(next==2){
menoy/=2;
System.out.println("金钱减少了一半,当前金钱为:"+menoy);
}else if(next==6){
String f=getFruit();
fruits.add(f);
System.out.println("获得了水果:"+f+",当前金钱为:"+menoy);
}else {
System.out.println("金钱没有发生改变,当前金钱为:"+menoy);
}
} private String getFruit() { String prefix="";
if(random.nextBoolean()){
prefix="好吃的";
}
return prefix+FruitsSame[random.nextInt(FruitsSame.length)]; } public Memento createMemento(){
Memento m=new Memento(menoy);
Iterator it=fruits.iterator();
while(it.hasNext()){
String fruit=(String)it.next();
if(fruit.startsWith("好吃的")){
m.addFruits(fruit);
}
}
return m;
} public void restoreMemento(Memento memento){
this.menoy=memento.getMenoy();
this.fruits=memento.getFruits();
} public String toString(){
return "Menoy:"+menoy+" ,Fruits:"+fruits;
} }

 SerializableMain类:

 package zyr.dp.test;

 import java.io.*;

 import zyr.dp.serializable.Gamer;
import zyr.dp.serializable.Memento; public class SerializableMain { private static String filename="game.dat";
public static void main(String[] args) {
Gamer gamer=new Gamer(100);
Memento memento=loadMemento();

16 if(memento==null){
17 memento=gamer.createMemento();
18 }else{
19 System.out.println("从上次保存处开始...");
20 gamer.restoreMemento(memento);
21 }

for(int i=0;i<100;i++){
System.out.println("当前状态:"+i);
System.out.println("当前金额:"+gamer.getMenoy());
gamer.bet();
if(gamer.getMenoy()<memento.getMenoy()/2){
System.out.println("金钱过少,恢复到以前的状态:");
gamer.restoreMemento(memento);
System.out.println("此时状态为:"+gamer);
}else if(gamer.getMenoy()>memento.getMenoy()){
System.out.println("金钱增多,保存当前状态:");
memento=gamer.createMemento();
saveMemento(memento);
System.out.println("此时状态为:"+gamer);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
private static void saveMemento(Memento memento) {
try {
ObjectOutput o=new ObjectOutputStream(new FileOutputStream(filename));
o.writeObject(memento);
o.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static Memento loadMemento() {
Memento memento=null;
ObjectInput in;
try {
in = new ObjectInputStream(new FileInputStream(filename));
memento=(Memento)in.readObject();
in.close();
} catch (FileNotFoundException e) {
System.out.println(e.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return memento;
}

}

运行结果:

初次运行:

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

 第二次运行:

从上次保存处开始...
当前状态: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的代码就能做到,职责明确是一种非常重要的是软件工程思想。

最新文章

  1. android知识点随笔
  2. Java Calendar 类的时间操作
  3. ACM/ICPC 之 平面几何-两直线关系(POJ 1269)
  4. Asp.Net 导出Excel数据文件
  5. char型变量理解
  6. const int *p与int *const p的区别(转:csdn,suer0101)
  7. CSS基础(背景、文本、列表、表格、轮廓)
  8. 矩阵经典题目六:poj 3070 Fibonacci
  9. ListView与DataTable传递数据
  10. form表单直接传文件
  11. 读取指定文件夹下的全部文件,可通过正则进行过滤,返回文件路径数组 -- 基于node的一个函数
  12. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
  13. index.go
  14. Docker &amp; ASP.NET Core (2):定制Docker镜像
  15. Egret的容器--删除对象,遮罩
  16. node一些相关
  17. 《Practical Vim》第十章:复制和粘贴
  18. Linux重启服务器步骤
  19. JSP指示元素&lt;%@ %&gt; 与指示类型
  20. acedSSSetFirst选择集夹点亮显实例

热门文章

  1. 怎么用 pytorch 查看 GPU 信息
  2. 应用安全 - 代码审计 - PHP
  3. [c#]Extesion method
  4. Windows + Ubuntu 16.04 双系统安装详细教程(转)
  5. JDK的下载与Java运行环境
  6. python学习第四十五天__name__用法和作用
  7. centos安装httprunner方法
  8. python学习笔记(7)文件的访问与函数式编程
  9. java.lang.NoClassDefFoundError: javax/transaction/Synchronization
  10. Linux基于Hadoop2.8.0集群安装配置Hive2.1.1及基础操作