设计模式再探-备忘录模式

简介: 最近在做一学期的语文课,每一节课结束的时候,需要将这节课上到哪儿了给记录下来;以便于下次再上课的时候接着上,这样一个需求。

一、背景介绍


最近在做一学期的语文课,每一节课结束的时候,需要将这节课上到哪儿了给记录下来;以便于下次再上课的时候接着上,这样一个需求。


于是乎想到了设计模式的备忘录模式,并且结合自己最近研究的面向对象和面向过程边界的梳理,再探状态模式有了全新的认识;甚至可以说过目不忘,希望将这样的一个能力和思考带给每一位读者朋友


要求:所有设计上的实现都要严格符合面向对象


二、思路&方案


  • 1.备忘录模式简介


  • 2.备忘录模式的类图


  • 3.备忘录模式中符合面向对象的地方


  • 4.备忘录模式按照面向对象还可以优化的地方


  • 5.备忘录模式的扩展——json转化、序列化和反序列化


三、过程


1.简介,定义


在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。


2.类图


e8a988ebc4e34223a1bdc2b2522253ce.png


package com.a7DesignPattern.a3BehaviorType.a07Memento;
/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/28 18:30
 */
public class Originator {
    private String state;
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public void SetMemento(Memento memento){
        this.state = memento.getState();
    }
    public Memento CreateMemento(){
        return new Memento(state);
    }
    public void Show(){
        System.out.println("state="+state);
    }
}


package com.a7DesignPattern.a3BehaviorType.a07Memento;
/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/28 18:29
 */
public class Memento {
    private String state;
    Memento(String state){
        this.state = state;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}


package com.a7DesignPattern.a3BehaviorType.a07Memento;
/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/28 18:34
 */
public class Caretaker {
    private Memento memento;
    public Memento getMemento() {
        return memento;
    }
    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}


package com.a7DesignPattern.a3BehaviorType.a07Memento;
/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/28 18:37
 */
public class Client {
    public static void main(String[] args) {
        Originator o = new Originator();
        o.setState("on");
        o.Show();
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(o.CreateMemento());
        o.setState("off");
        o.Show();
        o.SetMemento(caretaker.getMemento());
        o.Show();
    }
}


3.符合面向对象的地方


3.1.Originator 类中执行具体Memento的实例化,并且在构造函数中将状态值传进去进行保存

3.2.Originator 类中,进行对象状态恢复的时候,是将Memento对象传入到Originator对象中,进行具体状态值的恢复操作


4.按照面向对象还可以优化的地方


4.1.Memento类的构造是没必要的,可以直接在Caretaker中将Originator对象做一个深复制当做保留的带状态的对象


注:这里单独造了一个Memento对于读者理解的时候会更加的方便,因为将本来隐式的内容通过明确的类以及实例化的对象表示出来了更容易让读者理解


5.扩展-json转化、序列化


1.json转化可以对等为Caretaker类;通过将要保存的对象转化成了json的格式

2.序列化可以对等为Caretaker类;通过将要保存的对象转化成了二进制的格式


注:这两种扩展方式相较于备忘录而言,在存储传输上更加方便;下面也提供了json转化以及序列化的一个demo


package com.tfjy.util;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import java.io.*;
public class damo {
    private static final File SAVE_FILE = new File("D:" + File.separator + "demo.Class");
    public static void saveObject(Object object) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SAVE_FILE));
        oos.writeObject(object); // 序列化
        oos.close();
    }
    public static Object loadObject() throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SAVE_FILE));
        Object obj = ois.readObject(); // 反序列化
        ois.close();
        return obj;
    }
    public static void main(String[] args) throws Exception {
        //将类中重写的toString方法注释之后    ,下面json转化的例子才能实现
        String json = JSONObject.toJSONString(new Class(new Person("p",11),"class",12));
        System.out.println(json);
        //将类中重写的toString方法的注解打开之后,下面序列化和反序列化的例子才能实现
        saveObject(new Class(new Person("p",11),"class",12));// 序列化
        Class c = (Class)loadObject();
        System.out.println(c); // 反序列化
    }
    public static class Person implements Serializable {
        private String name;
        private int age;
        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 Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
//        @Override
//        public String toString() {
//            return "Person{" +
//                    "name='" + name + '\'' +
//                    ", age=" + age +
//                    '}';
//        }
    }
    public static class Class implements Serializable{
        private Person person;
        private String name;
        @JSONField(serialize = false)
        private int age;
        public Person getPerson() {
            return person;
        }
        public void setPerson(Person person) {
            this.person = person;
        }
        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;
        }
//        @Override
//        public String toString() {
//            return "Class{" +
//                    "person=" + person +
//                    ", name='" + name + '\'' +
//                    ", age=" + age +
//                    '}';
//        }
        public Class(Person person) {
            this.person = person;
        }
        public Class(Person person, String name, int age) {
            this.person = person;
            this.name = name;
            this.age = age;
        }
    }
}


四、总结


  • 1.再探备忘录模式和之前的理解完全不同,多了几个维度就将它瞬间转化成自己的知识了


  • 2.通过json转化、序列化和备忘录放到一起去对比,又通透了很多


  • 3.结合设计模式的类型,要解决的场景再理解起来更明确了


  • 4.这次对于设计模式的总结又上了一个层次;之前备忘录模式和状态模式总混,现在对于两者的边界非常清晰


五、升华


1.通过从底层明确边界之后,向上再梳理的时候会产生一种降维打击的效果

2.设计模式就是将知识敲碎了再重组的一个过程


扩展:今天还看了一下fastjson的源码,其中的通过判断注解不进行序列化的逻辑。下面是对应的一个截图


8073daebd57749d581e3dbb82f370425.png

相关文章
|
1月前
|
设计模式 存储 Java
【设计模式】备忘录模式
【设计模式】备忘录模式
|
2月前
|
设计模式 存储 Java
浅谈设计模式 - 备忘录模式(十五)
浅谈设计模式 - 备忘录模式(十五)
33 0
|
4月前
|
设计模式 存储 Java
Java设计模式【十九】:备忘录模式
Java设计模式【十九】:备忘录模式
26 0
|
6月前
|
设计模式 存储 Java
【设计模式——学习笔记】23种设计模式——备忘录模式Memento(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——备忘录模式Memento(原理讲解+应用场景介绍+案例介绍+Java代码实现)
55 0
|
12天前
|
存储 设计模式 安全
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道
备忘录模式是一种行为设计模式,允许在不破坏对象封装性的情况下保存和恢复对象的内部状态。该模式通过创建备忘录对象来存储发起人的状态信息,发起人可根据需要创建和恢复备忘录。管理者则负责保存和管理备忘录,但无法访问其内容。备忘录模式简化了状态管理,支持撤销操作和历史记录功能,提高了系统的灵活性和可用性。在实际应用中,备忘录模式常用于文本编辑器、游戏和数据库事务处理等场景,确保对象状态的安全恢复和有效管理。通过备忘录模式,开发人员可以更好地控制对象状态的变化,提升软件系统的健壮性和用户体验。
29 1
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道
|
3月前
|
设计模式 存储 Java
聊聊Java设计模式-备忘录模式
备忘录模式(Memento Design Pattern),也叫快照(Snapshot)模式。指在不违背封装原则前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。
38 0
聊聊Java设计模式-备忘录模式
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——10备忘录模式
Golang设计模式——10备忘录模式
27 0
|
3月前
|
设计模式 存储 前端开发
【设计模式】之备忘录模式
备忘录模式是一种有用的设计模式,在前端开发中可以应用于保存和恢复用户界面状态、实现撤销和重做功能等场景。通过封装对象状态并提供恢复机制,备忘录模式提高了代码灵活性和可维护性。然而,在使用备忘录模式时需要注意内存占用和代码复杂度等问题。
43 0
|
4月前
|
设计模式 存储
二十三种设计模式全面解析-深入探究备忘录模式:保留过去,预见未来
二十三种设计模式全面解析-深入探究备忘录模式:保留过去,预见未来
|
6月前
|
设计模式 存储 数据库
行为型设计模式05-备忘录模式
行为型设计模式05-备忘录模式
30 0