备忘录模式是一种软件 设计模式 :在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
为什么要使用备忘录模式备忘录模式用于保存和恢复对象的状态,相信大家看过我前面的拙作就会想到原型模式也能保存一个对象在某一个时刻的状态,那么两者有何不同的呢?原型模式保存的是当前对象的所有状态信息,恢复的时候会生成与保存的对象完全相同的另外一个实例;而备忘录模式保存的是我们关心的在恢复时需要的对象的部分状态信息,相当于快照。备忘录模式大家肯定都见过,比如在玩游戏的时候有一个保存当前闯关的状态的功能,会对当前用户所处的状态进行保存,当用户闯关失败或者需要从快照的地方开始的时候,就能读取当时保存的状态完整地恢复到当时的环境,这一点和VMware上面的快照功能很类似。
备忘录模式的角色浏览器回退:浏览器一般有浏览记录,当我们在一个网页上点击几次链接之后,可在左上角点击左箭头回退到上一次的页面,然后也可以点击右箭头重新回到当前页面
数据库备份与还原:一般的数据库都支持备份与还原操作,备份即将当前已有的数据或者记录保留,还原即将已经保留的数据恢复到对应的表中
编辑器撤销与重做:在编辑器上编辑文字,写错时可以按快捷键 Ctrl z 撤销,撤销后可以按 Ctrl y 重做
虚拟机生成快照与恢复:虚拟机可以生成一个快照,当虚拟机发生错误时可以恢复到快照的样子
Git版本管理:Git是最常见的版本管理软件,每提交一个新版本,实际上Git就会把它们自动串成一条时间线,每个版本都有一个版本号,使用 git reset --hard 版本号 即可回到指定的版本,让代码时空穿梭回到过去某个历史时刻
棋牌游戏悔棋:在棋牌游戏中,有时下快了可以悔棋,回退到上一步重新下
Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。
备忘录模式的核心是备忘录类以及用于管理备忘录的负责人类的设计
二、代码
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 }
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved