备忘录模式 命令模式

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是Memento设计模式 3.实施Memento设计模式 4.何时使用纪念图案 5. JDK中的Memento模式 6.下载源代码

1.简介

有时有必要记录对象的内部状态。 在实现检查点和“撤消”机制时,这是必需的,该机制使用户退出尝试性操作或从错误中恢复。 您必须将状态信息保存在某处,以便可以将对象还原到以前的状态。 但是对象通常封装了部分或全部状态,使得其他对象无法访问它,并且无法在外部保存。 暴露此状态将违反封装,这可能会损害应用程序的可靠性和可扩展性。

可以使用Memento模式完成此操作,而无需暴露对象的内部结构。 需要捕获其状态的对象称为始发者。

为了说明Memento模式的用法,我们来看一个示例。 我们将创建一个包含两个双精度类型字段的类,并在其上运行一些数学运算。 我们将为用户提供撤消操作。 如果用户不满意某些操作后的结果,则用户可以调用撤消操作,该操作会将对象的状态恢复到最后保存的点。

该示例还包括一个保存点机制,用户可以使用该保存点机制来保存对象的状态。 我们还将提供各种撤消操作。 一个简单的撤消操作会将对象状态恢复到先前的保存点。 具有指定保存点的撤消操作将还原对象的特定状态,而全部撤消操作将删除对象的所有保存状态,并在创建对象时将其恢复为初始化状态。

在实施模式之前,让我们进一步了解Memento设计模式。

2.什么是Memento设计模式

Memento模式的目的是在不违反封装的情况下捕获并外部化对象的内部状态,以便以后可以将对象恢复为该状态。

图1

纪念

  • 存储原始对象的内部状态。 纪念品可以根据原始作者的判断存储尽可能多的原始作者内部状态。
  • 防止发起者以外的对象访问。 备忘录有效地具有两个接口。 Caretaker看到与Memento的接口很狭窄-它只能将Memento传递给其他对象。 相反,Originator看到了一个广泛的接口,该接口使它可以访问将自身恢复到先前状态所需的所有数据。 理想情况下,仅允许产生纪念品的始发者访问纪念品的内部状态。

鼻祖

  • 创建一个包含其当前内部状态快照的纪念品。
  • 使用纪念品恢复其内部状态。

看守人

  • 负责纪念品的保管。
  • 切勿操作或检查纪念品的内容。

当客户端想要保存发起者的状态时,它向发起者请求当前状态。 发起者将恢复其状态所需的所有那些属性存储在称为Memento的单独对象中,并将其返回给客户端。 因此,在给定的时间点,可以将Memento视为包含另一个对象的内部状态的对象。 Memento对象必须对除原始者之外的所有对象隐藏原始者变量值。 换句话说,它应保护其内部状态,以防止除发起者以外的其他对象访问。 为此,在允许始发者访问其内部状态的同时,应将Memento设计为提供对其他对象的受限访问。

当客户希望将发起者恢复到其先前的状态时,它只是将备忘录传递回发起者。 始发者使用包含在memento中的状态信息,并将自身返回到存储在Memento对象中的状态。

3.实施Memento设计模式

package com.javacodegeeks.patterns.mementopattern;public class Originator {private double x;private double y;private String lastUndoSavepoint;CareTaker careTaker;public Originator(double x, double y,CareTaker careTaker){this.x = x;this.y = y;this.careTaker = careTaker;createSavepoint("INITIAL");}public double getX(){return x;}public double getY(){return y;}public void setX(double x) {this.x = x;}public void setY(double y) {this.y = y;}public void createSavepoint(String savepointName){careTaker.saveMemento(new Memento(this.x, this.y), savepointName);lastUndoSavepoint = savepointName;}public void undo(){setOriginatorState(lastUndoSavepoint);}public void undo(String savepointName){setOriginatorState(savepointName);}public void undoAll(){setOriginatorState("INITIAL");careTaker.clearSavepoints();}private void setOriginatorState(String savepointName){Memento mem = careTaker.getMemento(savepointName);this.x = mem.getX();this.y = mem.getY();}@Overridepublic String toString(){return "X: "+x+", Y: "+y;}}

上面是Originator类,其对象状态应保存在备忘录中。 该类包含两个double类型的字段xy ,并且还引用了CareTaker 。 的CareTaker用来保存和检索代表该状态的纪念品对象Originator对象。

在构造函数中,我们使用createSavepoint方法保存了对象的初始状态。 此方法创建一个memento对象,并请求看护者照顾该对象。 我们使用了一个lastUndoSavepoint变量,该变量用于存储上次保存的lastUndoSavepoint的键名,以实现undo操作。

该类提供三种类型的undo操作。 不带任何参数的undo方法将还原最后保存的状态,以保存点名称作为参数的undo将还原以该特定保存点名称保存的状态。 undoAll方法要求看护者清除所有保存点并将其设置为初始状态(创建对象时的状态)。

package com.javacodegeeks.patterns.mementopattern;public class Memento {private double x;private double y;public Memento(double x, double y){this.x = x;this.y = y;}public double getX(){return x;}public double getY(){return y;}
}

Memento类用于存储的状态Originator和照顾接受者存储。 该类没有任何设置方法,它仅用于获取对象的状态。

package com.javacodegeeks.patterns.mementopattern;import java.util.HashMap;
import java.util.Map;public class CareTaker {private final Map<String, Memento>savepointStorage = new HashMap<String, Memento>();public void saveMemento(Memento memento,String savepointName){System.out.println("Saving state..."+savepointName);savepointStorage.put(savepointName, memento);}public Memento getMemento(String savepointName){System.out.println("Undo at ..."+savepointName);return savepointStorage.get(savepointName);}public void clearSavepoints(){System.out.println("Clearing all save points...");savepointStorage.clear();}}

上面的类是用于存储和提供请求的memento对象的看护者类。 该类包含saveMemento方法用于保存memento对象, getMemento方法用于返回请求memento对象,以及clearSavepoints方法用于清除所有保存点,并删除所有已保存的memento对象。

现在,让我们测试示例。

package com.javacodegeeks.patterns.mementopattern;public class TestMementoPattern {public static void main(String[] args) {CareTaker careTaker = new CareTaker();Originator originator = new Originator(5, 10, careTaker);System.out.println("Default State: "+originator);originator.setX(originator.getY()*51);System.out.println("State: "+originator);originator.createSavepoint("SAVE1");originator.setY(originator.getX()/22);System.out.println("State: "+originator);originator.undo();System.out.println("State after undo: "+originator);originator.setX(Math.pow(originator.getX(),3));originator.createSavepoint("SAVE2");System.out.println("State: "+originator);originator.setY(originator.getX()-30);originator.createSavepoint("SAVE3");System.out.println("State: "+originator);originator.setY(originator.getX()/22);originator.createSavepoint("SAVE4");System.out.println("State: "+originator);originator.undo("SAVE2");System.out.println("Retrieving at: "+originator);originator.undoAll();System.out.println("State after undo all: "+originator);}}

上面的代码将导致以下输出。

Saving state...INITIAL
Default State: X: 5.0, Y: 10.0
State: X: 510.0, Y: 10.0
Saving state...SAVE1
State: X: 510.0, Y: 23.181818181818183
Undo at ...SAVE1
State after undo: X: 510.0, Y: 10.0
Saving state...SAVE2
State: X: 1.32651E8, Y: 10.0
Saving state...SAVE3
State: X: 1.32651E8, Y: 1.3265097E8
Saving state...SAVE4
State: X: 1.32651E8, Y: 6029590.909090909
Undo at ...SAVE2
Retrieving at: X: 1.32651E8, Y: 10.0
Undo at ...INITIAL
Clearing all save points...
State after undo all: X: 5.0, Y: 10.0

在上面的代码中,我们创建了一个CareTaker对象,然后将其分配给Originator对象。 然后,将xy的值分别设置为5和10。然后,对x一些运算并将对象的状态保存为“ SAVE1”。

经过更多的操作后,我们调用了undo方法来还原对象的最后状态,该状态在输出中会清楚显示。 然后,我们执行了一些操作,然后再次将对象的状态保存为“ SAVE2,SAVE3和SAVE4”。

然后,我们问Originator恢复SAVE2状态和呼叫undoAll方法,设置对象的初始状态,并删除所有保存点。

请注意,在上面的示例中, Originator负责向护理者提供其纪念品。 原因是我们不想将这种责任赋予用户。 在我们的示例中,用户只需要请求保存点和对象状态的恢复。 在许多情况下,看护人会由其他类别的人在发起人外部进行操作(如上图所示)。

4.何时使用纪念图案

在以下情况下,请使用Memento模式:

  • 必须保存对象状态(部分状态)的快照,以便以后可以将其恢复到该状态,并且
  • 获取状态的直接接口将公开实现细节并破坏对象的封装。

5. JDK中的Memento模式

  • java.util.Date
  • java.io.Serializable

6.下载源代码

这是关于Memento设计模式的课程。 您可以在此处下载源代码: MementoDesignPattern-Project

翻译自: https://www.javacodegeeks.com/2015/09/memento-design-pattern.html

备忘录模式 命令模式

备忘录模式 命令模式_备忘录设计模式示例相关推荐

  1. 《设计模式详解》行为型模式 - 命令模式

    命令模式 6.3 命令模式 6.3.1 概述 6.3.2 结构 6.3.3 案例实现 6.3.4 优缺点 6.3.5 使用场景 6.3.6 JDK 源码 - Runnable 完整的笔记目录:< ...

  2. 设计模式 — 行为型模式 — 命令模式

    目录 文章目录 目录 命令模式 应用场景 代码示例 命令模式 命令模式的目的是解耦调用操作的对象(调用者)和提供实现的对象(接收者). 命令模式的思路是在调用者和接收者之间插入一个命令类(Comman ...

  3. 设计模式-行为型模式-命令模式

    设计模式-行为型模式-命令模式 基础 以一个MIS系统为栗子 MIS 管理信息系统(Management Information System,MIS)是一个以人为主导的,利用计算机硬件.软件和网络设 ...

  4. 行为模式(模板模式命令模式备忘录模式)

    目录 模板方法模式(Template) 介绍 实现 命令模式(Command) 介绍 实现 备忘录模式(Memento) 介绍 实现 模板方法模式(Template) 一个抽象类公开定义了执行它的方法 ...

  5. Java设计模式(代理模式-模板方法模式-命令模式)

    Java设计模式Ⅴ 1.代理模式 1.1 代理模式概述 1.2 静态代理 1.2.1 静态代理概述 1.2.2 代码理解 1.3 动态代理之JDK代理 1.3.1 动态代理之JDK代理概述 1.3.2 ...

  6. 『设计模式』再谈麦当劳的点单模式--命令模式(Command)

    23种设计模式+额外常用设计模式汇总 (持续更新) 麦当劳,我三期设计模式拿你举例子了,私信联系我打钱!!! 概述 命令模式又称为行动(Action) 模式或交易(Transaction) 模式. 命 ...

  7. memento模式_Java中的Memento设计模式-示例教程

    memento模式 记忆模式是行为设计模式之一 . 当我们要保存对象的状态以便以后可以恢复时,可以使用Memento设计模式. 使用Memento模式以这种方式实现该目的,即无法在对象外部访问对象的已 ...

  8. java设计模式迭代器模式_Java中的迭代器设计模式–示例教程

    java设计模式迭代器模式 迭代器模式是一种行为模式,它用于提供遍历一组对象的标准方式. Iterator模式在Java Collection Framework中得到了广泛使用,其中Iterator ...

  9. java memento_memento模式_Java中的Memento设计模式-示例教程

    memento模式 记忆模式是行为设计模式之一 . 当我们要保存对象的状态以便以后可以恢复时,可以使用Memento设计模式. 使用Memento模式以这种方式实现该目的,即无法在对象外部访问对象的已 ...

最新文章

  1. 深度学习 Optimizer 梯度下降优化算法总结
  2. Apache 访问权限修改
  3. 计算机二级web题目(1)--web基础
  4. 前端学习(1841):前端面试题之react和vue区别
  5. STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出
  6. cacti更改web登录密码
  7. 为什么要使用GraphQL?
  8. linux中swi指令,Linux系统调用、新增系统调用方法
  9. FFA 2021 专场解读 - 实时数据湖
  10. pix 506E拨号上网设置
  11. 一篇述说“山寨”的文章,转过来大家看看。
  12. 计算机无法验证签名,你如何解决电脑无法验证数字签名的问题
  13. Django实现websocket聊天室
  14. OpenVINO系列19_face_detection检测人脸并做标记
  15. TOJ 5138: 数字游戏
  16. Docker学习(二)进阶
  17. iOS集成Cordova开发教程遇到的问题
  18. 将中文转换成拼音的组件类的pinyin
  19. 为DB2 新增加的用户不能直接使用db2命令的解决办法
  20. JavaSE学习摘要

热门文章

  1. CF1598E-Staircases【计数】
  2. jzoj6067-[NOI2019模拟2019.3.18]More?More!【dp】
  3. CF1139D-Steps to One【期望dp,莫比乌斯反演】
  4. P2257-YY的GCD【莫比乌斯反演】
  5. 【前缀和】【DP】登机(jzoj 5535)
  6. [bzoj 4811] 由乃的OJ(贪心 + 树链剖分)
  7. Spark入门(三)Idea构建spark项目
  8. 互联网账户系统的具体实现
  9. Java 程序员必须掌握的 5 个注解
  10. Java IO: InputStream