设计模式(十九)备忘录模式

本文详细介绍了备忘录模式的概念、结构、实例及优缺点,展示了如何在Java中实现备忘录模式,以便于在软件系统中实现撤销功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 . 模式动机

  • 让软件系统可以回到误操作以前,就相当于撤销上一步。备忘录模式就是为了实现这个功能的模式。
  • 因此我们需要记录一个对象的内部状态,在具体实现过程中,需要实现备份点和撤销机制,必须事先将状态保存起来。

二 . 模式定义

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

三 . 模式结构

(图片来源于网络)

  • Originator:原发器
  • Memento:备忘录
  • Caretaker:负责人

四 . 模式实列

  • 我们做一个简单的备忘录模式实例,就是回到误操作的前一步,记录三个变量用户,密码和电话。
  • UML图
    在这里插入图片描述
  • Originator原发器
public class UserInfoDTO {
    private String account;
    private String password;
    private String telNo;

    public UserInfoDTO(String account, String password, String telNo) {
        this.account = account;
        this.password = password;
        this.telNo = telNo;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelNo() {
        return telNo;
    }

    public void setTelNo(String telNo) {
        this.telNo = telNo;
    }
    public Memento saveMemento(){
        return new Memento(account,password,telNo);
    }
    public void restoreMemento(Memento memento){
        this.account = memento.getAccount();
        this.password = memento.getPassword();
        this.telNo = memento.getTelNo();
    }
    public void show(){
        System.out.println("account:"+this.account);
        System.out.println("password:"+this.password);
        System.out.println("telNo:"+this.telNo);
    }
}

  • 备忘录
public class Memento {
    private String account;
    private String password;
    private String telNo;

    public Memento(String account, String password, String telNo) {
        this.account = account;
        this.password = password;
        this.telNo = telNo;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelNo() {
        return telNo;
    }

    public void setTelNo(String telNo) {
        this.telNo = telNo;
    }
}
  • Caretaker负责人
public class Caretaker {
    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}
  • 测试类
public class Client {
    public static void main(String[] args) {
        UserInfoDTO user = new UserInfoDTO("唐楠","123456","18049453816");
        Caretaker caretaker = new Caretaker();
        //将状态存储在Caretaker里
        caretaker.setMemento(user.saveMemento());
        System.out.println("被篡改后:");
        user.setAccount("asdsdqwd");
        user.setPassword("111111111");
        user.setTelNo("dsadqwe12321");
        user.show();
        //在Caretaker里找到之前存储的旧状态并撤销到旧的状态
        System.out.println("恢复后:");
        user.restoreMemento(caretaker.getMemento());
        user.show();
    }
}
  • 测试结果
E:\Java\jdk1.8.0_171\bin\java.exe "-javaagent:E:\idea\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=57942:E:\idea\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "E:\Java\jdk1.8.0_171\jre\lib\charsets.jar;E:\Java\jdk1.8.0_171\jre\lib\deploy.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;E:\Java\jdk1.8.0_171\jre\lib\javaws.jar;E:\Java\jdk1.8.0_171\jre\lib\jce.jar;E:\Java\jdk1.8.0_171\jre\lib\jfr.jar;E:\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;E:\Java\jdk1.8.0_171\jre\lib\jsse.jar;E:\Java\jdk1.8.0_171\jre\lib\management-agent.jar;E:\Java\jdk1.8.0_171\jre\lib\plugin.jar;E:\Java\jdk1.8.0_171\jre\lib\resources.jar;E:\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Design pattern\out\production\Design pattern" Memento备忘录模式.Client
被篡改后:
account:asdsdqwd
password:111111111
telNo:dsadqwe12321
恢复后:
account:唐楠
password:123456
telNo:18049453816

Process finished with exit code 0

五 . 模式分析

  • 由于备忘录中存储的是原发器的中间状态,因此需要防止原发器意外的其他对象访问备忘。
  • 对于原发起,可以调用备忘录所有信息,允许原发器访问返回先前

六 . 模式优缺点

  • 优点
    • 提供一种状态恢复的实现机制,使得用户可以方便的回到一个特点的历史步骤。
    • 实现了信息的封装
  • 缺点
    • 资源消耗过大,如果类的成员变量太多,就不可避免占用大量内存,并且每次保存状态都需要消耗内存,因此编辑软件不可能无限制的撤销。

七 . 适用环境和应用

  • 适用环境
    • 保存一个对象的在某一时刻的状态
    • 如果一个接口让其他对象得到这些状态,这将会暴露对象的实现细节并且破坏对象的封装性,一个对象不希望外交直接访问内部状态,通过负责人可以间接访问其内部状态。
  • 应用
    • 几乎所有的文字或图片编辑软件都提供了撤销功能。
      的撤销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值