设计模式(12)---备忘录模式

备忘录模式   Memento (行为型模式)

 

1.概述

备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

例如:一些软件提供的撤销功能,游戏的存档读档功能。

 

2.结构图

3.代码

 1 /*
 2  * 原发器类   Originator 
 3  */
 4 public class Role {
 5 
 6     private int level ;
 7     private int life ;
 8     
 9     public Role() {
10         this.level = 1 ;
11         this.life = 100 ;
12     }
13 
14     public int getLevel() {
15         return level;
16     }
17 
18     public void setLevel(int level) {
19         this.level = level;
20     }
21 
22     public int getLife() {
23         return life;
24     }
25 
26     public void setLife(int life) {
27         this.life = life;
28     }
29     
30     //保存状态
31     public RoleMemento save(){
32         return new RoleMemento(this.level,this.life) ;
33     }
34     
35     //恢复状态
36     public void load(RoleMemento memento){
37         this.level = memento.getLevel() ;
38         this.life = memento.getLife() ;
39     }
40     
41     public void display(){
42         System.out.println("当前等级"+this.level+",生命"+this.life);
43     }
44 
45 }
 1 /*
 2  * 备忘录类
 3  */
 4 public class RoleMemento {
 5 
 6     private int level ;
 7     private int life ;
 8     
 9     public RoleMemento() {
10         // TODO Auto-generated constructor stub
11     }
12 
13     public RoleMemento(int level, int life) {
14         this.level = level;
15         this.life = life;
16     }
17     
18     public int getLevel() {
19         return level;
20     }
21 
22     public void setLevel(int level) {
23         this.level = level;
24     }
25 
26     public int getLife() {
27         return life;
28     }
29 
30     public void setLife(int life) {
31         this.life = life;
32     }
33     
34     
35     
36 
37 }
 1 /*
 2  * 负责人类
 3  */
 4 public class Caretaker {
 5 
 6     private RoleMemento memento ;
 7     public Caretaker() {
 8         // TODO Auto-generated constructor stub
 9     }
10     public RoleMemento getMemento() {
11         return memento;
12     }
13     public void setMemento(RoleMemento memento) {
14         this.memento = memento;
15     }
16     
17     
18 
19 }
 1 public class Test {
 2 
 3     public static void main(String[] args) {
 4         Caretaker caretaker = new Caretaker() ;
 5         Role role = new Role() ;
 6         role.display();
 7         
 8         System.out.println("存档");
 9         caretaker.setMemento(role.save());
10         
11         System.out.println("打了一堆小怪后");
12         role.setLevel(3);
13         role.setLife(500);
14         role.display();
15         
16         System.out.println("遇到了一个Boss,然后挂了");
17         System.out.println("读档");
18         role.load(caretaker.getMemento());
19         
20         role.display();
21 
22     }
23 
24 }

原发器类也就是一个具体的业务类,它包含一些用于存储成员数据的属性。

备忘录类提供了与原发器相对应的属性(可以是全部,也可以是部分)用于存储原发器的状态。

负责人类用于保存备忘录对象。

 

4.多次撤销

在负责人类中加入列表、堆栈等集合来存储备忘录对象。在客户类中,加入一个下标来记录当前状态的位置,每次存档,下标则加1。

 

5.优点

(1)要保存的细节封装在了客户类中,如果以后需要加入攻击力这样的属性,客户类不需要修改。

(2)它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

 

6.适用场景

(1)功能比较复杂,需要记录属性历史的类,使用备忘录模式能使其恢复到先前的状态,实现撤销操作。

7.备忘录的封装

备忘录是一个很特殊的对象,只有原发器对它拥有控制的权力,负责人只负责管理,而其他类无法访问到备忘录,因此我们需要对备忘录进行封装。

在C++中可以使用friend关键字,让原发器类和备忘录类成为友元类,互相之间可以访问对象的一些私有的属性;

在Java语言中可以将原发器类和备忘录类放在一个包中,让它们之间满足默认的包内可见性,也可以将备忘录类作为原发器类的内部类,使得只有原发器才可以访问备忘录中的数据,其他对象都无法使用备忘录中的数据。

原文地址:https://www.cnblogs.com/mengchunchen/p/5771337.html