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

news2024/11/26 11:55:31

目录

  • 一、背景介绍
  • 二、思路&方案
  • 三、过程
    • 1.简介,定义
    • 2.类图
    • 3.符合面向对象的地方
    • 4.按照面向对象还可以优化的地方
    • 5.扩展-json转化、序列化
  • 四、总结
  • 五、升华

一、背景介绍

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

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

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

二、思路&方案

  • 1.备忘录模式简介
  • 2.备忘录模式的类图
  • 3.备忘录模式中符合面向对象的地方
  • 4.备忘录模式按照面向对象还可以优化的地方
  • 5.备忘录模式的扩展——json转化、序列化和反序列化

三、过程

1.简介,定义

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

2.类图

在这里插入图片描述

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的源码,其中的通过判断注解不进行序列化的逻辑。下面是对应的一个截图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/760205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot使用JWT进行身份验证

JWT身份验证的流程 用户登录: 用户向服务器提供他们的用户名和密码。 服务器验证:服务器接收到请求,验证用户名和密码。 生成JWT:如果用户名和密码验证通过,服务器将创建一个 JWT。 JWT 包含了一些数据(称…

JS混淆原理2023

JS混淆原理 •eval 加密 通过eval去执行函数通常和webpack打包拼接一起使用• 变量混淆 ​ 变量名混淆,十六进制替换,随机字符串替换• 属性加密 ​ 一套组合算法,将属性加密生成• 控制流平坦化 逻辑处理块统一加上前驱逻辑块&#xff0c…

kubeproxy和service dns整体原理

iptables知识 五条链 iptables是linux内核集成的IP信息过滤规则,负责将发往主机的网络包进行分发,转换等。当客户端请求服务器的某个服务时,请求信息会先通过网卡进入服务器内核,这时iptables会对包进行过滤,决定这些…

Docker安装卸载

说明:在大型的项目开发中,各种开发软件所需的环境各不相同,所需的依赖也时常发生冲突。而Docker将开发软件,和所需的依赖、函数库、配置打包成一个可移植的镜像文件,在Docker的容器中运行,使用沙箱机制&…

线程基础和等待唤醒机制

一、基础 1、进程和线程 进程:进程是用来加载指令、管理内存、管理IO的,操作系统会以进程为单位分配系统资源(cpu、内存等资源),进程是资源分配的最小单位线程:线程是操作系统cpu调度的最小单位&#xff…

用Linux模拟实现进度条

1.设置文件,以及创建makefile 2.make 的相关用法 make存在的目的就是为了在文件多的时候,gcc 文件名,你可能要输入很多次,但是make的存在,一句make指令就可以完成了。 process [生成文件] : 与之有关的文件。下一行就…

Sparse Input Novel View Synthesis

文章目录 1.《Vision transformer for nerf-based view synthesis from a single input image》【WACV2023】摘要动机方法实验 2.《SparseFusion: Distilling View-conditioned Diffusion for 3D Reconstruction》【CVPR23】动机Related workApproach总结 3.《NerfDiff: Single…

NetSuite ERP顾问的进阶之路

目录 1.修养篇 1.1“道”是什么?“器”是什么? 1.2 读书这件事儿 1.3 十年计划的力量 1.3.1 一日三省 1.3.2 顾问损益表 1.3.3 阶段课题 2.行为篇 2.1协作 2.2交流 2.3文档管理 2.4时间管理 3.成长篇 3.1概念能力 3.1.1顾问的知识结构 …

TCP缓冲区和4次挥手调优

目录 如何修改TCP缓冲区才能兼顾并发数量与传输速度? 四次挥手性能调优 1,为什么建立连接是三次握手,而关闭连接需要四次挥手呢? 2.四次挥手的流程,注意5个状态 3.主动方优化 4,被动方调优 最后 如何修改TCP缓冲区才能兼顾并发数量与传输速度&…

NUC972开发板学习过程

1、搭建linux环境的过程,设置交叉编译器的环境变量过程中会出现各种问题; 解决方法: 第一步、一定要Ubuntu系统换源,换源后sudo apt-get update; 第二步、sudo apt-get install lib32stdc6 第三步、使用 vim编辑器…

创新指南|连锁经营,先从单店盈利模型做起

随着数字化时代的到来,数据成为了企业创新的重要资源。有价值的数据的涌现和发展为企业提供了前所未有的机会。数据为创新带来新动力,创造了新产品和服务、产生了新的商业模式,并带来了新的创业机会。数据驱动的创新已成为许多企业创新的重要…

4.1.tensorRT基础(1)-概述

目录 前言1. tensorRT基础概述2. tensorRT补充知识2.1 什么是tensorRT?2.2 tensorRT特性2.3 tensorRT工作流程2.4 常见方案2.5 tensorRT库文件 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记&#…

springboot+ElasticSearch+Logstash+Kibana实现日志采集ELK

ElasticSearchLogstashKibana日志管理 一、什么是ELK? ELK是Elasticsearch、Logstash、Kibana的简称,这三者是核心套件,但并非全部。一般情况下我们可以把日志保存在日志文件当中,也可以把日志存入数据库当中。但随着业务量的增加&#xf…

2.多线程-初阶(上)

文章目录 1. 认识线程(Thread)1.1 概念1.2 第一个多线程程序1.3 创建线程1.3.1方法1 继承 Thread 类1.3.2方法2 实现 Runnable 接口 1.4 多线程的优势-增加运行速度1.5 PCB、PID、进程和线程之间的关系 2. Thread(/θred/) 类及常见方法2.1 Thread 的常见…

《Maven实战》读后感

目录 一、一些思考1、为什么平时编写的Java项目也叫做Maven项目?2、平常的Java项目目录为什么长这样,可以改变目录结构吗?3、对于Maven项目来说,Maven能帮我们做什么?4、为什么一定需要Maven私服,不要行不行…

easyrecovery数据恢复软件2023免费版下载

easyrecovery数据恢复软件2023免费版下载是一款操作简单、功能强大数据恢复软件,通过easyrecovery可以从硬盘、光盘、U盘、数码相机、手机等各种设备中恢复被删除或丢失的文件、图片、音频、视频等数据文件。 EasyRecovery数据恢复软件是一款功能强大的数据恢复软件&#xff0c…

卡尔曼滤波的理解

看了B站up主DR_CAN讲的卡尔曼滤波(链接)。up讲的非常好,强烈推荐,看完终于明白了卡尔曼滤波的奥秘。下面是我对其中内容的注解,或者说自己的理解。大部分推导省略了,但保留了算法的思想脉络。 引入 首先看…

Verilog基础之十七、锁相环PLL

目录 一、前言 1.1 背景 1.2 PLL结构 二、工程设计 2.1 PLL IP核配置 2.2 设计代码 2.3 测试代码 2.4 仿真结果 2.5 常见问题 一、前言 1.1 背景 若将一个FPGA工程看做一个人体,时钟的重要性丝毫不亚于心脏对于人体的重要性,时钟的每一个周期对…

支付、购物车、搜索、文件上传、登录、还款、订单测试怎么做?

支付功能怎么测试:1、从功能方面考虑: 1)、正常完成支付的流程; 2)、支付中断后继续支付的流程; 3)、支付中断后结束支付的流程; 4)、单订单支付的流程; 5&am…

【无标题】(前沿)

Java编程语言 目前为止最流行的 是Java编程语言 但是编程与语言有很多中php。phyone。 c c. c# java html. css javascript vue() 说到计算机有很多同学会说,就有很多人会说35的节点,我问一下同学们现在哪一个行业,是没有35岁的节点&#x…