大话设计模式——8.原型模式(Prototype Pattern)

news2024/11/17 22:21:09
1.介绍

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。属于创建型模式。
UML图:
在这里插入图片描述
1)浅拷贝: 指创建一个新的对象,然后将原始对象的字段值复制到新对象中。如果字段是基本类型,直接复制其值;如果字段是引用类型,则复制其引用,新对象和原对象将共享同一份引用指向相同的内存地址。一般实现Cloneable接口,重写clone()方法

2)深拷贝: 指创建一个新的对象,然后将原始对象的字段值复制到新对象中。但与浅拷贝不同的是,对于引用类型的字段,深拷贝会递归地复制其所指向的对象,而不是复制引用本身。一般实现Serializable接口进行序列化再反序列化。

2.示例

一个学校的学生信息有着许多可以复用的,因此可以使用原型模式进行设计,快速创建复用的信息。
1)学生对象:Student

public class Student implements Cloneable, Serializable {


    private String name;

    private String sex;

    /**
     * 年级
     */
    private String grade;

    /**
     * 学校
     */
    private String schoolName;

    /**
     * 学科
     */
    private List<String> subjects;

    /**
     * 浅拷贝 ,调用顶级父类Object的方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }


    /**
     * 深拷贝
     *
     * @return
     */
    public Student deepClone() {
        try {
            // 转换二进制输出流,序列化
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bao);
            oos.writeObject(this);

            //  输入流转换,反序列化,拷贝形成新的对象
            ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bai);
            return (Student) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public Student() {
    }

    public Student(String name, String sex, String grade, String schoolName, List<String> subjects) {
        this.name = name;
        this.sex = sex;
        this.grade = grade;
        this.schoolName = schoolName;
        this.subjects = subjects;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }

    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    public List<String> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<String> subjects) {
        this.subjects = subjects;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", grade='" + grade + '\'' +
                ", schoolName='" + schoolName + '\'' +
                ", subjects=" + subjects +
                '}';
    }
}

2)运行:

public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {

        Student student1 = new Student("大美", "女", "一年级", "大大小学", Arrays.asList("数学", "语文", "英语"));

        // 浅拷贝
        Student student2 = student1.clone();
        student2.setName("小美");
        student2.getSubjects().set(1,"da");

        // 深拷贝
        Student student3 = student1.deepClone();
        student3.setName("小庄");
        student3.setSex("男");
        student3.getSubjects().set(1,"hh");

        System.out.println(student1);
        System.out.println(student2);
        System.out.println(student3);
        // 浅拷贝,引用类型数据指向共同的地址
        System.out.println(student2.getSubjects() == student1.getSubjects());
        System.out.println(student3.getSubjects() == student1.getSubjects());
    }
}
3.总结

1)优点:
a. 当创建新的对象实例较为复杂时,可以简化对象的创建过程,提高新实例的创建效率;
b. 可以辅助实现撤销操作,采取深克隆的方式保存对象的状态,将对象复制⼀份并将其状态保存起来,在需要的时候使其恢复到历史状态。

2)缺点:
a. 每个类都需要重写克隆方法,比较繁琐且不符合开闭原则;
b. 深克隆的实现编写较为复杂,且对象间存在多重嵌套引用时,其中的每个必须支持深克隆。

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

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

相关文章

MySQL高阶SQL语句

文章目录 MySQL高阶SQL语句MySQL常用查询1、按关键字排序1.1 语法1.2 ASC和DESC1.3 对数据表中信息进行排序1.3.1 普通排序1.3.2 结合where进行条件过滤1.3.3 对多个字段进行排序 2、区间判断及查询不重复记录2.1 and/or —— 且/或2.1.1 普通查询2.1.2 嵌套/多条件查询 2.2 di…

Java毕业设计-基于springboot开发的校园志愿者管理系统-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、管理员功能3、志愿者功能 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发的校园志愿者管理系统…

“AI程序员”Devin大杀四方后,人类程序员开始了他们的反击......

“首个AI程序员”Devin发布后&#xff0c;大有要替代人类程序员的意味。 在当时发布之初&#xff0c;Devin展示了AI自主处理各种程序任务的案例。其中Devin生成“生命游戏”的演示是最让我震惊的。 所谓“生命游戏”&#xff0c;是由英国数学家约翰何顿康威&#xff08;John …

CPU设计实战-外设接口介绍与测试

GPIO 内置寄存器&#xff0c;BASE地址由外设所在设备接口处决定&#xff0c;这样就可以确定每个寄存器的地址&#xff1b; 要使用输出先要使能&#xff0c;要用中断也先要使能&#xff1b; 测试实验-数码管驱动 数码管与GPIO的输出接口连接 编写汇编语言 1.使能输出端口 2…

游戏 AI 反作弊|基于时序行为数据的自瞄外挂检测方案,附方案详情!

游戏AI反作弊&#xff0c;上次跟大家分享了基于时序行为数据的透视外挂检测方案&#xff0c;本次跟大家分享 基于时序行为数据的自瞄外挂检测方案&#xff0c;大家记得点赞收藏&#xff01; 游戏 AI 反作弊|内附解决方案详情&#xff01;-CSDN博客 基于时序行为数据的自瞄外挂检…

【正点原子Linux连载】第二十二章 Linux INPUT子系统实验摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南

1&#xff09;实验平台&#xff1a;正点原子ATK-DLRK3568开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id731866264428 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/docs/boards/xiaoxitongban 第二十…

DNS协议 是什么?说说DNS 完整的查询过程?

一、是什么 DNS&#xff08;Domain Names System&#xff09;&#xff0c;域名系统&#xff0c;是互联网一项服务&#xff0c;是进行域名和与之相对应的 IP 地址进行转换的服务器 简单来讲&#xff0c;DNS相当于一个翻译官&#xff0c;负责将域名翻译成ip地址 IP 地址&#…

【数据分享】1929-2023年全球站点的逐日平均海平面压力(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

笔记本作为其他主机显示屏(HDMI采集器)

前言&#xff1a; 我打算打笔记本作为显示屏来用&#xff0c;连上工控机&#xff0c;这不是贼方便吗 操作&#xff1a; 一、必需品 HDMI采集器一个 可以去绿联买一个&#xff0c;便宜的就行&#xff0c;我的大概就长这样 win10下载 PotPlayer 软件 下载链接&#xff1a;h…

考了PMP证后工资大概是多少 ?

PMP自1999年引入国内以来&#xff0c;大家对这个证书的了解并不深&#xff0c;每年考试的人数也不多。但随着越来越多的企业认可PMP认证&#xff0c;目前考证的人数不断增加&#xff0c;几乎所有与项目管理相关的人都知道这个证书的重要性。这个证书在招聘要求中出现频率较高&a…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

【Codesys】-扫描添加失败,手动添加第三方模块,真·DC模式的高速计数模块

欧姆龙耦合器&#xff08;NX-ECC201&#xff09;和高速计数模块&#xff08;NX-EC0132&#xff09;单独使用。扫描设备添加到Codesys中&#xff0c;会报错&#xff0c;无法自动添加。需要手动添加。内容方法如下。如遇到其他第三方耦合器解决方式也同下面一样。记录一下&#x…

三位数组合-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第42讲。 三位数组合&#…

MySql实战--事务到底是隔离的还是不隔离的

第3篇文章和你讲事务隔离级别的时候提到过&#xff0c;如果是可重复读隔离级别&#xff0c;事务T启动的时候会创建一个视图read-view&#xff0c;之后事务T执行期间&#xff0c;即使有其他事务修改了数据&#xff0c;事务T看到的仍然跟在启动时看到的一样。也就是说&#xff0c…

【zip技巧】4种方法,删除ZIP压缩包密码

之前给大家介绍了zip压缩包加密方法&#xff0c;那么zip压缩包取消密码&#xff0c;大家了解多少呢&#xff1f;有密码的情况下&#xff0c;有哪些方法可以取消密码&#xff1f;无密码又该如何取消密码&#xff1f;今天总结四个方法分享给大家。 一、 最原始的方法&#xff0…

“Hands-free AG audio“和“Stereo“的区别

用蓝牙连接耳机后&#xff0c;发现有两个选项 一个音量大&#xff0c;一个音质好&#xff0c;好奇去查了查。 “Hands-free AG audio”&#xff08;自由通话音频&#xff09;是指一种技术或功能&#xff0c;可以使您在进行通话时无需使用手部操作或接触设备。这通常适用于汽车…

Spring:面试八股

文章目录 参考Spring模块CoreContainerAOP 参考 JavaGuide Spring模块 CoreContainer Spring框架的核心模块&#xff0c;主要提供IoC依赖注入功能的支持。内含四个子模块&#xff1a; Core&#xff1a;基本的核心工具类。Beans&#xff1a;提供对bean的创建、配置、管理功能…

智能文档处理技术综述

一、 智能文档处理介绍 智能文档处理&#xff08;Intelligent Document Processing, IDP&#xff09;是利用人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、计算机视觉&#xff08;CV&#xff09;、自然语言处理&#xff08;NLP&#xff09;等技术…

【WEEK4】 【DAY5】AJAX第二部分【中文版】

2024.3.22 Friday 接上文【WEEK4】 【DAY4】AJAX第一部分【中文版】 目录 8.4.Ajax异步加载数据8.4.1.新建User.java8.4.2.在pom.xml中添加lombok、jackson支持8.4.3.更改tomcat设置8.4.4.修改AjaxController.java8.4.5.新建test2.jsp8.4.5.1.注意&#xff1a;和WEB-INF平级&…

R语言学习——Rstudio软件

R语言免费但有点难上手&#xff0c;是数据挖掘的入门级别语言&#xff0c;拥有顶级的可视化功能。 优点&#xff1a; 1统计分析&#xff08;可以实现各种分析方法&#xff09;和计算&#xff08;有很多函数&#xff09; 2强大的绘图功能 3扩展包多&#xff0c;适合领域多 …