北风设计模式课程---备忘录(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),或者称迪米特法则( ...
随机推荐
- ELK 学习
[Udemy] ES 7 and Elastic Stack - part 1 [Udemy] ES 7 and Elastic Stack - part 2 [Udemy] ES 7 and Ela ...
- ecshop启用gzip后,后台不能打开不能访问的问题
上传测试的时候,站点显示无法打开.随后我用网址打开根目录的robots文件.图片.静态页···全部可以正常打开··· 我尴尬···一一检查后,我就怀疑是不是客户当初设置gzip压缩的问题了.但连后台都 ...
- 建立 Active Directory域 ----学习笔记
第五章 建立 Active Directory域 1.工作组和域的理解 a.工作组是一种平等身份环境,各个计算机之间各个为一个独立体,不方便管理和资源共享. b.域环境一般情况下满足两类需求, ...
- linux中cut命令
cut命令 cut常用参数 cut命令用来显示行中的指定部分,删除文件中指定字段. 说明:该命令有两项功能,其一是用来显示文件的内容,它依次读取由参数file所指明的文件,将它们的内容输出到标准输出上 ...
- [Bzoj2004][Hnoi2010]Bus 公交线路(状压dp&&矩阵加速)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 看了很多大佬的博客才理解了这道题,菜到安详QAQ 在不考虑优化的情况下,先推$dp ...
- Neo4j 不区分大小写的模糊查询匹配
问题:当图数据库中存储的节点的名字为英文时,就会遇到大小写不匹配问题. 使用不区分大小写的正则表示式可以解决以上问题. Cpyher的where语法里支持正则表达式 ,其语法为 : =~ &quo ...
- 移动端300ms延迟原理,穿透、遮罩层滑动导致下面滑动总结
遮罩层滑动导致下面滑动 1,阻止弹层滑动,使用默认事件,使用这种方式弹层不能滑动 document.getElementById("model").addEventListener ...
- 学Python的第五天
最近忙着学MySQL,但是小编也不会放弃学Python!!! 因为热爱所以学习~ 好了各位,进入正题,由于时间问题今天学的不是很多.... #!/usr/bin/env python # -*- co ...
- css:鼠标点击出现有颜色的边框?如何解决
今天遇到上图这样出现有颜色的边框 解决办法: css设置属性 outline:none;
- python笔记(2)---不定长参数
python自定义函数中有两种不定长参数, 第一种是*name:加了星号 * 的参数会以元组(tuple)的形式导入 第二种是**name:加了星号 * *的参数会以字典(dict)的形式导入 *na ...