备忘录模式-对象行为型

简介: 原理 备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。

原理

备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。

组成

 

  备忘录模式所涉及的角色有三个:备忘录(Memento)角色、发起人(Originator)角色、负责人(Caretaker)角色

备忘录(Memento)角色又如下责任:

  (1)将发起人(Originator)对象的内战状态存储起来。备忘录可以根据发起人对象的判断来决定存储多少发起人(Originator)对象的内部状态。

  (2)备忘录可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。

发起人(Originator)角色有如下责任:

  (1)创建一个含有当前的内部状态的备忘录对象。

  (2)使用备忘录对象存储其内部状态。

负责人(Caretaker)角色有如下责任:

  (1)负责保存备忘录对象。

  (2)不检查备忘录对象的内容。

 

 “自述历史”模式

  所谓“自述历史”模式(History-On-Self Pattern)实际上就是备忘录模式的一个变种。在备忘录模式中,发起人(Originator)角色、负责人(Caretaker)角色和备忘录(Memento)角色都是独立的角色。虽然在实现上备忘录类可以成为发起人类的内部成员类,但是备忘录类仍然保持作为一个角色的独立意义。在“自述历史”模式里面,发起人角色自己兼任负责人角色。

  “自述历史”模式的类图如下所示:

  

  备忘录角色有如下责任:

  (1)将发起人(Originator)对象的内部状态存储起来。

  (2)备忘录可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。

  发起人角色有如下责任:

  (1)创建一个含有它当前的内部状态的备忘录对象。

  (2)使用备忘录对象存储其内部状态。

  客户端角色有负责保存备忘录对象的责任。

  源代码

  窄接口MementoIF,这是一个标识接口,因此它没有定义出任何的方法。

public interface MementoIF {

}

  发起人角色同时还兼任负责人角色,也就是说它自己负责保持自己的备忘录对象。

  

 
public class Originator {

    public String state;
    /**
     * 改变状态
     */
    public void changeState(String state){
        this.state = state;
        System.out.println("状态改变为:" + state);
    }
    /**
     * 工厂方法,返还一个新的备忘录对象
     */
    public Memento createMemento(){
        return new Memento(this);
    }
    /**
     * 将发起人恢复到备忘录对象所记录的状态上
     */
    public void restoreMemento(MementoIF memento){
        Memento m = (Memento)memento;
        changeState(m.state);
    }
    
    private class Memento implements MementoIF{
        
        private String state;
        /**
         * 构造方法
         */
        private Memento(Originator o){
            this.state = o.state;
        }
        private String getState() {
            return state;
        }
        
    }
}
 

  客户端角色类

 
public class Client {

    public static void main(String[] args) {
        Originator o = new Originator();
        //修改状态
        o.changeState("state 0");
        //创建备忘录
        MementoIF memento = o.createMemento();
        //修改状态
        o.changeState("state 1");
        //按照备忘录恢复对象的状态
        o.restoreMemento(memento);
    }

}
 

  由于“自述历史”作为一个备忘录模式的特殊实现形式非常简单易懂,它可能是备忘录模式最为流行的实现形式。

  

 

目录
相关文章
阿里云商标注册入口(查询/申请/交易/管理)
阿里云商标注册页面、商标自助申请系统、商标近似查询、商标交易、商标管理后台、商标续展等操作入口
5849 5
阿里云商标注册入口(查询/申请/交易/管理)
|
11月前
|
消息中间件 存储 负载均衡
2024消息队列“四大天王”:Rabbit、Rocket、Kafka、Pulsar巅峰对决
本文对比了 RabbitMQ、RocketMQ、Kafka 和 Pulsar 四种消息队列系统,涵盖架构、性能、可用性和适用场景。RabbitMQ 以灵活路由和可靠性著称;RocketMQ 支持高可用和顺序消息;Kafka 专为高吞吐量和低延迟设计;Pulsar 提供多租户支持和高可扩展性。性能方面,吞吐量从高到低依次为
3979 1
|
监控 Java
Zabbix【部署 02】Zabbix-Java-Gateway安装配置使用(使用Zabbix-Java-Gateway通过JMX监控Java应用程序实例分享)
Zabbix【部署 02】Zabbix-Java-Gateway安装配置使用(使用Zabbix-Java-Gateway通过JMX监控Java应用程序实例分享)
799 0
|
JavaScript 前端开发 API
对mixin的理解
Vue.js的Mixin是代码重用的关键,它合并组件选项,如数据、方法和生命周期钩子。创建一个JavaScript对象,然后在组件中通过`mixins`选项引用它。当多个Mixin有相同属性,组件数据优先,钩子函数按顺序执行。避免命名冲突,保持Mixin简洁、独立。使用局部Mixin限制影响范围,全局Mixin需谨慎,因为它们影响所有组件。考虑使用Composition API、插件或高阶组件作为替代策略。正确使用Mixin能提升代码的维护性和复用性。
|
JSON JavaScript 前端开发
Node.js 18 新版发布,天猪带你解读新特性
Node.js 18 新版发布,天猪带你解读新特性
1290 0
|
SQL 算法 Java
百万级别数据Excel导出优化
这篇文章不是标题党,下文会通过一个仿真例子分析如何优化百万级别数据Excel导出。
1320 0
百万级别数据Excel导出优化
|
关系型数据库 MySQL 数据库
mysql:Windows修改MySQL数据库密码(修改或忘记密码)
mysql:Windows修改MySQL数据库密码(修改或忘记密码)
1903 0
mysql:Windows修改MySQL数据库密码(修改或忘记密码)
|
程序员 开发者
SegmentFault:中文开发者专业问答社区
网易科技讯 6月7日消息,SegmentFault(简称SF)的目标是做一个纯粹的程序员问答社区,国外知名IT问答网站StackOverflow是SegmentFault的学习对象。SegmentFault避免建设成类似Quora的社会化问答社区,比起那些更注重社交关系的问答网站,SegmentFault更加注重问题之间的关系。 在SegmentFault,所有人都是平等的,不管回答者是什么人,答案能解决问题,用
775 0
SegmentFault:中文开发者专业问答社区
|
iOS开发
iOS开发:block死循环及__weak弱引用提前释放的问题解决
block死循环及__weak弱引用提前释放的问题解决
460 0
|
存储 C++ 容器
C++中的unordered_map和map区别
`unordered_map` 类模板和 `map` 类模板都是描述了这么一个对象:它是由 `std::pair<const Key, value>` 组成的可变长容器,这个容器中每个元素存储两个对象,也就是 `key` - `value` 对。
978 0