zoukankan      html  css  js  c++  java
  • 004-行为型-07-备忘录模式(Memento)

    一、概述

      又叫做快照模式(Snapshot Pattern)或Token模式

      保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

      意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

      主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

      备忘录模式和状态模式:备忘录模式是对象表示状态,状态模式是用类来表示状态。

    1.1、适用场景

      1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

      (1)一个类需要保存它的对象的状态(相当于Originator角色)
      (2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)
      (3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存
      (4)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态

    1.2、优缺点

      优点: 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 2、实现了信息的封装,使得用户不需要关心状态的保存细节。

      缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

    1.3、类图角色及其职责

      

      1、Originator(原生者):需要被保存状态以便恢复的那个对象,负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。

      2、Memento(备忘录):该对象由Originator创建,主要负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状

    态所需要的所有数据。

      3、Caretaker(管理者):负责在适当的时间保存/恢复Originator对象的状态,负责备忘录Memento,不能对Memento的内容进行访问或者操作。

    1.4、演进过程

    首先,新建一个Person类,他就是Originator(原生者)

    /*
     * Originator(原生者)
     */
    public class Person {
        /*
         * 姓名,年龄,性别就是结构图中的state,状态属性
         */
        //姓名
        private String name;
        //年龄
        private int age;
        //性别
        private String sex;
    
        public Person() {
            super();
        }
    
        public Person(String name, int age, String sex) {
            super();
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public void display() {
            System.out.println("name:" + name + ",sex:" + sex + ",age:" + age);
        }
    
        //创建一个备份
        public Memento createMemento() {
            return new Memento(name, age, sex);
        }
    
        //恢复一个备份
        public void setMemento(Memento memento) {
            this.name = memento.getName();
            this.age = memento.getAge();
            this.sex = memento.getSex();
        }
    }

    接着,创建一个Memento(备忘录),他和Originator的基本结构是一样的

    /*
     * Memento(备忘录)
     */
    public class Memento {
        //姓名
        private String name;
        //年龄
        private int age;
        //性别
        private String sex;
    
        public Memento() {
            super();
        }
    
        public Memento(String name, int age, String sex) {
            super();
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }

    创建管理者Caretaker(管理者)角色

    /*
     * Caretaker(管理者)
     */
    public class Caretaker {
        //持有一个对Memento的引用
        private Memento memento;
    
        public Memento getMemento() {
            return memento;
        }
    
        public void setMemento(Memento memento) {
            this.memento = memento;
        }
    }

    测试

        @Test
        public void test() {
            Person person = new Person("小明",18,"男");
            //打印
            person.display();
    
            //创建一个管理者
            Caretaker caretaker = new Caretaker();
    
            //创建一个备份
    //        Memento memento = person.createMemento();
            caretaker.setMemento(person.createMemento());
    
            person.setName("小红");
            person.setAge(17);
            person.setSex("女");
            //打印
            person.display();
    
            //备份还原
            person.setMemento(caretaker.getMemento());
            //打印
            person.display();
        }

    输出

    name:小明,sex:男,age:18
    name:小红,sex:女,age:17
    name:小明,sex:男,age:18

    二、扩展

    2.1、spring

    org.springframework.binding.message.StateManageableMessageContext

    数据库的事务管理。

  • 相关阅读:
    react结合antd4.0和umi3.0的404界面
    小程序自带组件自定义tabbar
    移动安全学习清单
    跨域资源共享 CORS 详解(转)
    docker常用命令总结
    XSS绕过小结
    mysql的order by注入
    本地文件包含漏洞利用姿势
    XSS绕过<>进行测试
    clamscan+clam-freshclam.service服务启停
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11573983.html
Copyright © 2011-2022 走看看