前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >备忘录模式

备忘录模式

作者头像
用户1148394
发布2018-01-09 16:59:41
5550
发布2018-01-09 16:59:41
举报
文章被收录于专栏:余林丰

备忘录模式,望文生义就知道它是用来做备忘的,或者可以直接说是“备份”。当需要保存当前状态,以便在不久要恢复此状态时,就可以使用“备忘录模式”。将当前”状态“备份,是不是又new一个类,然后将每个字段方法copy过去就可以了呢?或者说使用我们之前clone方法做深复制浅复制呢?其实不然,在《大话设计模式》中,作者提到了原因,这样会暴露更多的细节给客户端,不符合我们面向对象的思想。什么是暴露更多的细节给客户端?我们来看下面一段代码。

代码语言:javascript
复制
 1 package day_27_memento;
 2 
 3 /**
 4  * @author turbo
 5  *
 6  * 2016年9月27日
 7  */
 8 public class Client {
 9 
10     /**
11      * @param args
12      */
13     public static void main(String[] args) {
14         /*状态一*/
15         Test nowTest = new Test();
16         nowTest.setField("状态一");
17         
18         /*备份状态*/
19         Test backUpTest = new Test();
20         backUpTest.setField(nowTest.getField());
21         
22         /*修改状态一*/
23         nowTest.setField("修改状态一,改为状态二");
24         
25         /*还原状态*/
26         nowTest.setField(backUpTest.getField());
27     }
28 
29 }

Test类中只有一个field字段,不再贴出代码。由上代码我们可以看到,如果要备份的字段较多,在客户端里就会暴露过多的细节。而我们希望的是,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这句话的后面两句是啥意思呢?捕获一个对象的内部状态——值得是要获得需要备份的状态(或者简单理解为字段),该备份状态要保存在另外一个类并要有对象自己来读取。

我们还是先来看代码。在备忘录模式中涉及到三个基本的类,一个是原始类,即需要备份的状态类,一个是备份类,即具体存储状态,还有一个管理者,用来提供备份状态类。

首先实现原始类,在这个类里除去该类本身自有的方法,还要有一个创建备份和获取备份的两个方法。

代码语言:javascript
复制
 1 package day_27_memento;
 2 
 3 /**
 4  * 发起人,它要负责创建一个备忘录Memento用来记录当前时刻它的状态
 5  * @author turbo
 6  *
 7  * 2016年9月27日
 8  */
 9 public class Originator {
10     private String state;
11 
12     public String getState() {
13         return state;
14     }
15 
16     public void setState(String state) {
17         this.state = state;
18     }
19     
20     /**
21      * 显示状态
22      */
23     public void show(){
24         System.out.println("state : " + state);
25     }
26     
27     /**
28      * 创建备忘录
29      * @return 备份的状态
30      */
31     public Memento createMemento(){
32         return (new Memento(state));  //在这句我们可以看到将状态细节封装在了内部,对外部透明。
33     }
34     
35     /**
36      * 获取备份
37      * @param memento 备份类
38      */
39     public void setMememto(Memento memento){
40         state = memento.getState();
41     }
42 }

备忘类。

代码语言:javascript
复制
 1 package day_27_memento;
 2 
 3 /**
 4  * 备忘类
 5  * @author turbo
 6  *
 7  * 2016年9月27日
 8  */
 9 public class Memento {
10     private String state;
11     
12     public String getState() {
13         return state;
14     }
15 
16     public Memento(String state){
17         this.state = state;
18     }
19 }

接着来看看这个管理者类。

代码语言:javascript
复制
 1 package day_27_memento;
 2 
 3 /**
 4  * 管理者
 5  * @author turbo
 6  *
 7  * 2016年9月27日
 8  */
 9 public class Caretaker {
10     private Memento memento;
11 
12     public Memento getMemento() {
13         return memento;
14     }
15 
16     public void setMemento(Memento memento) {
17         this.memento = memento;
18     }
19     
20 }

管理者类就是用来提供备忘录类的。最后我们来看客户端代码。

代码语言:javascript
复制
 1 package day_27_memento;
 2 
 3 /**
 4  * @author turbo
 5  *
 6  * 2016年9月27日
 7  */
 8 public class Main {
 9     public static void main(String[] args){
10         /*当前状态*/
11         Originator originator = new Originator();
12         originator.setState("On");
13         originator.show();
14         /*备份当前状态*/
15         Caretaker caretaker = new Caretaker();
16         caretaker.setMemento(originator.createMemento());
17         /*更新状态*/
18         originator.setState("Off");
19         originator.show();
20         /*备份状态*/
21         originator.setMememto(caretaker.getMemento());
22         originator.show();
23     }
24 }

从代码16行、21行,我们能看到实际上就是书中所说,“有时一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取”。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-09-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档