北风设计模式课程---备忘录(Memento)模式
北风设计模式课程---备忘录(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的代码就能做到,职责明确是一种非常重要的是软件工程思想。
北风设计模式课程---备忘录(Memento)模式的更多相关文章
- C++设计模式实现--备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比較适用于功 ...
- 北风设计模式课程---访问者模式(Visitor)
北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...
- 北风设计模式课程---访问者(Visitor)模式
北风设计模式课程---访问者(Visitor)模式 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- 北风设计模式课程---解释器模式(Interpreter Pattern)
北风设计模式课程---解释器模式(Interpreter Pattern) 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用 ...
- 北风设计模式课程---外观模式(Facade)总结
北风设计模式课程---外观模式(Facade)总结 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用户获得装备,我可以先装备 ...
- 北风设计模式课程---开放封闭原则(Open Closed Principle)
北风设计模式课程---开放封闭原则(Open Closed Principle) 一.总结 一句话总结: 抽象是开放封闭原则的关键. 1."所有的成员变量都应该设置为私有(Private)& ...
- 北风设计模式课程---接口分离原则(Interface Segregation Principle)
北风设计模式课程---接口分离原则(Interface Segregation Principle) 一.总结 一句话总结: 接口分离原则描述为 "客户类不应被强迫依赖那些它们不需要的接口& ...
- 北风设计模式课程---最少知识原则(Least Knowledge Principle)
北风设计模式课程---最少知识原则(Least Knowledge Principle) 一.总结 一句话总结: 最少知识原则(Least Knowledge Principle),或者称迪米特法则( ...
随机推荐
- 《深入浅出WPF》学习总结之学前知识
一个WPF应用的组成结构 Properties:存放程序资源(图标.图片.静态字符串等) References:标记了当前项目需要引用哪些其他项目App.xmal:程序的主体.在Windows系统里, ...
- git日常开发中的使用
作者:python技术人 博客:https://www.cnblogs.com/lpdeboke 1.在远程新建一个仓库,可以使github.gitlib或者bitbucket,这里以bitbucke ...
- Notepad++-第一篇命令行语句执行之编译、运行Java
1.让Notepad++编译和运行Java,在电脑上要已经配置好了Java的开发环境 2.在Notepad++上面的选项栏中找到 Plugins--->Plugin Admin 3.在Avail ...
- CSS3制作的垂直口风琴1
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 看漫画就能学SQL,简直太cool了
对于SQl, 很多人学不会的原因是从一开始就没明白,学这东西能干啥,学会了能有什么用.甚至有些人不知道'SQL'应该怎么读,以至于一开始兴致勃勃,但是学到一半放弃了. 注意:'sql'真的不能读成'烧 ...
- django实例收集
django笔记(一)(模板渲染变量.字典.for循环.索引.条件语句) django笔记(二) django环境准备与笔记(三) django笔记(四) django笔记(五) Views的补充 w ...
- Python 爬虫 校花网
爬虫:是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 福利来了 校花网 ,首先说为什么要爬这个网站呢,第一这个网站简单爬起来容易,不会受到打击,第二呢 你懂得.... 1.第一步,需要下 ...
- element 弹框关闭报错
<template> <el-container style="padding: 00px 20px 0px 20px"> <el-dialog ti ...
- java 中Shallow Heap与Retained Heap的区别
Shallow Size Shallow Size是对象本身占据的内存的大小,不包含其引用的对象.对于常规对象(非数组)的Shallow Size由其成员变量的数量和类型来定,而数组的ShallowS ...
- JavaScript版EAN码校验算法
<script type="text/javascript"> $(document).ready(function () { $("#btnCalc&q ...