【设计模式】—— 备忘录模式Memento

  模式意图

  这个模式主要是想通过一个对象来记录对象的某种状态,这样有利于在其他需要的场合进行恢复。

  该模式还有跟多可以扩展的地方,比如可以记录多个时间的状态,每个角色都有可以扩展的空间,完全看业务场景而定。

  应用场景

  1 保存对象某一时刻的状态

  2 避免直接暴露接口,破坏封装性

  模式结构

  Originator 是备忘录的发起者,记录状态的对象

class Originator{
    private String state;
    public Memento ceateMemento() {
        return new Memento(state);
    }
    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }
    public String getState(){
        return this.state;
    }
    public void setState(String state){
        this.state = state;
        System.out.println("Current state = "+this.state);
    }
}

  Memento 备忘录角色,通常用于保存某种状态

class Memento{
    private String state;
    public Memento(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}

  Caretaker 备忘录的负责人,负责在恰当的时机,进行状态的恢复

class Caretaker{
    private Memento memento;
    public Memento retrieveMemento(){
        return this.memento;
    }
    public void saveMemento(Memento memento){
        this.memento = memento;
    }
}

  全部代码

package com.xingoo.test.design.memento;
class Originator{
    private String state;
    public Memento ceateMemento() {
        return new Memento(state);
    }
    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }
    public String getState(){
        return this.state;
    }
    public void setState(String state){
        this.state = state;
        System.out.println("Current state = "+this.state);
    }
}
class Memento{
    private String state;
    public Memento(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}
class Caretaker{
    private Memento memento;
    public Memento retrieveMemento(){
        return this.memento;
    }
    public void saveMemento(Memento memento){
        this.memento = memento;
    }
}
public class Client {
    private static Originator o = new Originator();
    private static Caretaker c = new Caretaker();
    public static void main(String[] args) {
        o.setState("On");
        //记录状态
        c.saveMemento(o.ceateMemento());
        //更改状态
        o.setState("Off");
        //更新状态
        o.restoreMemento(c.retrieveMemento());
    }
}

  运行结果

Current state = On
Current state = Off

  生活中的设计模式

 

  最近看了会 恶魔奶爸,挺扯淡的漫画。不过看到其中的女仆,让我想起了这种备忘录模式。

  主人在有什么重要的事情时,都会交给女仆记着,规定的时间在提醒自己。

  下面的主人就有一件很重要的事情,就是陪亲爱的小丽去看电影,于是他弄了一个笔记本,记录下了这个信息。女仆拿到笔记本,并在预先商量好的时间提醒主人。这里的笔记本就是上面的备忘录对象Memento,而这个模式中,主人就是备忘录的发起者,女仆是负责人。

  这里涉及到的备忘录是属于【白箱】的,也就是说,备忘录中的信息,可以被发起人和负责人看到。还有一种是【黑箱】的,主要是用了一种内部类继承这个备忘录对象,这样外部的负责人就得不到真正备忘录中的具体信息

  下面看下具体的实现,主人的代码如下:

 1 class Master{
 2     private String info;
 3     public String getInfo() {
 4         return info;
 5     }
 6     public void setInfo(String info) {
 7         this.info = info;
 8     }
 9     public Note createNote(String info){
10         return new Note(info);
11     }
12     public void action(Note note){
13         this.info = note.getInfo();
14         System.out.println("主人看到笔记,记起了 "+ this.info);
15     }
16     public void toDo(){
17         System.out.println("****主人正在..."+info);
18     }
19 }

  女仆的代码如下:

 1 class Maid{
 2     private Note note;
 3     public Note readNote(){
 4         System.out.println("女仆拿到笔记本");
 5         return this.note;
 6     }
 7     public void writeNote(Note note){
 8         System.out.println("女仆写笔记");
 9         this.note = note;
10     }
11 }

  备忘录的代码如下:

 1 class Note{
 2     private String info;
 3     public Note(String info) {
 4         this.info = info;
 5     }
 6     public void setInfo(String info){
 7         this.info = info;
 8         System.out.println("写笔记!");
 9     }
10     public String getInfo(){
11         System.out.println("读笔记!");
12         return info;
13     }
14 }

  全部代码:

 1 package com.xingoo.test.design.memento;
 2 class Note{
 3     private String info;
 4     public Note(String info) {
 5         this.info = info;
 6     }
 7     public void setInfo(String info){
 8         this.info = info;
 9         System.out.println("写笔记!");
10     }
11     public String getInfo(){
12         System.out.println("读笔记!");
13         return info;
14     }
15 }
16 class Master{
17     private String info;
18     public String getInfo() {
19         return info;
20     }
21     public void setInfo(String info) {
22         this.info = info;
23     }
24     public Note createNote(String info){
25         return new Note(info);
26     }
27     public void action(Note note){
28         this.info = note.getInfo();
29         System.out.println("主人看到笔记,记起了 "+ this.info);
30     }
31     public void toDo(){
32         System.out.println("****主人正在..."+info);
33     }
34 }
35 class Maid{
36     private Note note;
37     public Note readNote(){
38         System.out.println("女仆拿到笔记本");
39         return this.note;
40     }
41     public void writeNote(Note note){
42         System.out.println("女仆写笔记");
43         this.note = note;
44     }
45 }
46 public class LifeWithMaid {
47     public static void main(String[] args) {
48         Master master = new Master();
49         Maid maid = new Maid();
50         //主人想起了要做的事情
51         maid.writeNote(master.createNote("晚上6点,配小丽看电影"));
52         //主人忙其他的事情
53         master.setInfo("睡觉吃饭打豆豆!");
54         master.toDo();//主人正在做什么?
55         //时间到了,女仆提醒主人
56         master.action(maid.readNote());
57         master.toDo();//主人正在做什么?
58     }
59 }    

  运行结果

女仆写笔记
****主人正在...睡觉吃饭打豆豆!
女仆拿到笔记本
读笔记!
主人看到笔记,记起了 晚上6点,配小丽看电影
****主人正在...晚上6点,配小丽看电影

 

本文转自博客园xingoo的博客,原文链接:【设计模式】—— 备忘录模式Memento,如需转载请自行联系原博主。

时间: 2024-10-28 20:46:51

【设计模式】—— 备忘录模式Memento的相关文章

乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabcd 介绍 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到保存的状态. 示例 有一个Message实体类,某个对象对它的操作有Insert()方法,只有在插入时间符合要求的情况下才能插入成功,因此要求可以保存和恢复Message对象的状态,插入失败

设计模式之禅之设计模式-备忘录模式

<一:备忘录模式的定义        --->备忘录模式(Memento Pattern)提供了一种弥补真实世界缺陷的方法,让"后悔药"在程序的世界中真实可行        --->在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.        --->通俗地说,备忘录模式就是一个对象的备份模式,提供了一种程序数据的备份方法 二:备忘录模式的角色 ● Originator发起人角色      

学习php设计模式 php实现备忘录模式(Memento)_php技巧

一.意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样可以在以后把该对象的状态恢复到之前保存的状态. 二.备忘录模式结构图 三.备忘录模式中主要角色1.备忘录(Memento)角色: 存储发起人(Originator)对象的内部状态,而发起人根据需要决定备忘录存储发起人的哪些内部状态. 备忘录可以保护其内容不被发起人(Originator)对象之外的任何对象所读取.2.发起人(Originator)角色:创建一个含有当前的内部状态的备忘录对象 使用备忘录对象存

.net设计模式实例之备忘录模式(Memento Pattern)

一.备忘录模式简介(Brief Introduction) 备忘录模式(Memento Pattern),在不破坏封装的前提下,捕获一个对象的内部状态, 并在该对象之外保存这个状态.这样以后就可以就该对象恢复到原先保存的状态. 二.解决的问题(What To Solve) 当系统功能比较复杂,而且需要记录历史属性以便当需要时做恢复动作.Originator可以 根据保存的Memento信息还原到前一状态. 三.备忘录模式分析(Analysis)1.备忘录模式结构 Originator类:发起人.

PHP设计模式——备忘录模式

声明:本系列博客参考资料<大话设计模式>,作者程杰.                 备忘录模式又叫做快照模式或Token模式,在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.              UML类图:                              角色:                 1.发起人(GameRole):负责创建一个备忘录,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态.发

IOS设计模式-备忘录模式

内容大纲 如何存储记录 备忘录模式的基本原理 使用备忘录模式 优化存储方案 恢复UIView的状态 1.如何存储记录 在存储记录时,第一步我们需要用一把钥匙去打开一把锁.第二步,当我们打开锁之后就会有黑盒子,我们一开始还不知道里面有什么,所以是黑盒子. 1.存储记录的必要性 生活中,比如去超市购物有时候就需要在入口储物柜存放自己的包裹 2.记录的唯一标示 储物柜对应一把钥匙和号码标示. 3.存储记录与取出记录 ===========================================

Java设计模式--备忘录模式

备忘录模式(别名:标记) 在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态. Memento Pattern(Another Name: Token) Without violating encapsulation, capture and externalize an object original state so that the object can be restored to this state later. 类图

21、Python与设计模式--备忘录模式

一.游戏进度保存 打过游戏的朋友一定知道,大多数游戏都有保存进度的功能,如果一局游戏下来,忘保存了进度,那么下次只能从上次进度点开始重新打了.一般情况下,保存进度是要存在可持久化存储器上,本例中先以保存在内存中来模拟实现该场景的情形.以模拟一个战斗角色为例.首先,创建游戏角色. class GameCharacter(): vitality = 0 attack = 0 defense = 0 def displayState(self): print 'Current Values:' pri

c#设计模式-备忘录模式-备忘录对象被改变

问题描述 usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacetest3{classChess{privateint[,]a=newint[10,10];publicChess(){for(inti=0;i<10;i++){for(intj=0;j<10;j++)a[i,j]=0;}}publicvoidsetChes