【设计模式--创建型--原型模式】

news2024/11/26 2:38:01

设计模式--创建型--原型模式

    • 原型模式
      • 概述
      • 结构
      • 实现
      • 结果
    • 案例
      • 代码
      • 结果
      • 使用场景
    • 扩展(深\浅克隆)
      • 浅克隆演示:
      • 结果:
      • 使用深克隆(利用对象流)
      • 结果

原型模式

概述

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

结构

原型模式包含如下角色

  • 抽象原型类:规定了具体原型对象必须实现的clone()方法
  • 具体原型类:实现抽象原型的clone()方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的clone()方法来复制新的对象。

实现

原型模式的克隆分为浅克隆和深克隆。

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有对象地址。
    Java中的Object类中提供了clone()方法来实现浅克隆。
/**
 * 具体的原型类实现Cloneable接口  这里用Cloneable接口来当做抽象原型类
 */
public class RealizeType implements Cloneable{

    public RealizeType(){
        System.out.println("使用构造器创建具体的原型对象");
    };

    /**
     * 重写clone()方法
     * @return RealizeType
     */
    @Override
    public RealizeType clone() throws CloneNotSupportedException{
        System.out.println("clone具体原型对象成功");
        return (RealizeType) super.clone();
    }
}
public class Test01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建一个原型对象
        RealizeType realizeType = new RealizeType();
        // 调用RealizeType中的clone方法进行对象的克隆
        RealizeType clone = realizeType.clone();
        System.out.println("原型对象和克隆对象是否是同一个对象?"+ (clone == realizeType));
    }
}

结果

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4978f97be7a246caa286f5d6f9bfb63b.png

案例

用原型模式生成"三好学生"奖状
奖状除了获奖人信息不同,其他都相同,可以使用原型模式复制多个“三好学生奖状”,然后修改学生信息即可

代码

public class Citation implements Cloneable{
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException{
        return (Citation) super.clone();
    }
    public void info(){
        System.out.println(name + "同学的奖状");
    }
}
public class Test01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建奖状原型
        Citation citation = new Citation();
        citation.setName("张三");
        Citation clone = citation.clone();
        clone.setName("李四");
        citation.info();
        clone.info();
    }
}

结果

在这里插入图片描述

  • 这里虽然是浅拷贝但是name属性没有改变,是因为name是String类型,如果是引用类型并且还是浅拷贝,那么原型对象中的name是改变的,下面是深、浅克隆演示。

使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象
  • 性能和安全的要求比较高

扩展(深\浅克隆)

这里将上面的name属性放到一个student对象中,而Citation类中的Student属性就是引用属性

浅克隆演示:

public class Citation implements Cloneable{
  private Student stu;
  public Student getStu(){
    return stu;
  }
  public void setStu(Student stu){
    this.stu = stu;
  }

  @Override
  public Citation clone() throws CloneNotSupportedException{
    return (Citation) super.clone();
  }
  public void info(){
    System.out.println(stu.getName() + "同学的奖状");
  }
}
public class Student {
    private String name;

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}
public class Test01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建奖状原型
        Citation citation = new Citation();
        // 创建学生对象
        Student student = new Student();
        student.setName("张三");
        citation.setStu(student);
        citation.info();
        // 克隆
        Citation clone = citation.clone();
        // 重新设置学生姓名
        clone.getStu().setName("李四");
        citation.info();
        clone.info();
    }
}

结果:

在这里插入图片描述

说明:原型对象和克隆出来的对象中的student对象是同一个对象,修改其中一个,另一个的值也会改变。
这就是浅克隆的效果,对具体原型类中的引用数据类型进行引用的复制。

使用深克隆(利用对象流)

克隆时先将原型对象写入文件中,再读取。

public class Citation implements Cloneable, Serializable {
    private Student stu;
    public Student getStu(){
        return stu;
    }
    public void setStu(Student stu){
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException{
        return (Citation) super.clone();
    }
    public void info(){
        System.out.println(stu.getName() + "同学的奖状");
    }
}
public class Student implements Serializable {
    private String name;

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}
public class Test02 {
    public static void main(String[] args) throws Exception {
        // 创建奖状原型
        Citation citation = new Citation();
        // 创建学生对象
        Student student = new Student();
        student.setName("张三");
        citation.setStu(student);
        citation.info();
        // 创建对象输出流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/a.txt"));
        // 写对象
        oos.writeObject(citation);
        // 释放
        oos.close();
        // 创建对象输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/a.txt"));
        // 读取对象
        Citation citation1 = (Citation) ois.readObject();
        ois.close();
        citation1.getStu().setName("李四");
        citation.info();
        citation1.info();
    }
}

结果

在这里插入图片描述

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

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

相关文章

【MySQL】MySQL库的操作

MySQL库的操作 一、创建数据库创建数据库案例字符集和校验规则校验规则对数据库的影响 二、操纵数据库1、查看数据库2、查看当前正在使用的数据库3、使用数据库4、显示创建语句5、数据库删除6、数据库的修改7、备份和恢复8、查看连接情况 一、创建数据库 创建数据库的语法如下…

使用python绘制现有彩票记录走势图

在数据分析和可视化的领域中,彩票走势图是一个经典的例子,它可以展示彩票数字随时间的出现频率和趋势。这里使用英国使用EuroMillions彩票的历史数据作为示例,使用Python和Matplotlib库来创建一个简单的走势图。可以在以下网站搜索.csv文件。…

基于SSM的剧本杀预约系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

Promise与async/await的简单介绍

在 JavaScript 中,处理异步操作一直是开发者们面临的挑战之一。传统的回调函数方式往往导致代码难以维护、可读性差、易产生回调地狱等问题。为了解决这些问题,出现了 Promise 和 Async/Await 这两种处理异步操作的方式。 一、异步产生问题示例 当我们…

6.4 U-boot 移植

一、ST 官方 U-boot 编译测试 1. ST 官方 uboot 源码打补丁 1.1 获得 ST 官方的 uboot 源码 https://www.cnblogs.com/toutiegongzhu/p/17578847.html 这里可以看如何下载uboot源码。解压完后输入以下命令: cd stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/s…

什么是图片懒加载(image lazy loading)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

区块链媒体宣发:揭示优势与趋势,引领信息传播新时代

在数字化潮流中,区块链技术正以惊人的速度改变着传媒行业的格局。从区块链媒体宣发中获得的种种优势和未来的趋势,不仅为企业带来了新的推广途径,也在信息传播领域掀起了一场革命。本文将深入探讨区块链媒体宣发的优势以及未来的发展趋势。 1…

一款基于ESP32的迷你四足机器人

一、软件介绍 增加自定义动作模式,可以在小程序中自定义一个最多10个步骤的动作。 附件中:带自定模式固件bin.zip esp32c3固件文件 烧录下图设置 无串口版本esp32c3开发板烧录前先按住BOOT键再插线进入烧录模式,LoadMode选择USB。 二、AP…

计算机毕业设计 SpringBoot的医院门诊在线挂号系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

shiro反序列化漏洞复现

shiro反序列化漏洞复现 文章目录 shiro反序列化漏洞复现版本安装环境漏洞利用流量分析 版本 550 仅需要一个url 721 需要一个账号 安装环境 先配置国内源 安装docker apt-get install docker 安装docker-compose apt-get install docker-compose 拉取镜像 docker pull …

二分查找|滑动窗口|前缀和|LeetCode209: 长度最小的子数组

长度最短的子数组 作者推荐 【动态规划】【广度优先】LeetCode2258:逃离火灾 本文涉及的基础知识点 二分查找算法合集 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 滑动窗口 题目 给定一个含有 n 个正整数的数组和一个正整数 target…

Python开发运维:Python项目发布到K8S集群

目录 一、实验 1.Python项目发布到K8S集群 一、实验 1.Python项目发布到K8S集群 (1)获取应用程序代码 #把hello-python.tar.gz压缩包上传到k8s控制节点master1的root下,手动解压 tar zxvf hello-python.tar.gz (2&#xff0…

智能外呼有什么好处?

智能外呼是一种自动化的电话营销方式,利用AI智能外呼技术和大量数据分析,帮助企业实现与客户之间的高效、精准、个性化的客户沟通,还可以在客户服务、市场营销和销售等方面带来助力。那么,智能外呼有什么好处呢? 1. 提…

elasticsearch|大数据|elasticsearch低版本集群的部署安装和安全增强---密码设置问题

一, 版本问题 elasticsearch的高低版本划分标准为6.3,该版本之前的为低版本,6.3版本之后的包括6.3为高版本,这么划分主要是在安全性方面也就是x-pack插件的使用部署方面,低版本需要手动安装该安全插件,而…

【网络协议】LACP(Link Aggregation Control Protocol,链路聚合控制协议)

文章目录 LACP名词解释LACP工作原理互发LACPDU报文确定主动端确定活动链路链路切换 LACP和PAgP有什么区别?LACP与LAG的关系LACP模式更优于手动模式LACP模式对数据传输更加稳定和可靠LACP模式对聚合链路组的故障检测更加准确和有效 推荐阅读 LACP名词解释 LACP&…

同位素二氧化碳数据记录软件

同位素二氧化碳数据记录软件用于实现同位素二氧化碳分析仪数据的获取与存档,阀箱数据的获取、记录以及阀箱的远程操作,数据的FTP上传等功能。其主操作界面如下: 软件的左侧为操作目录区域,实现显示界面的切换和连接操作及其状态指…

GPIO的使用--USART串口通信--传感器控制数据

目录 一、串口通信 1、概念 2、原理图 3、使用步骤 (1)寻找串口位置 (2)确定引脚编号 (3)编写代码 4、实验结果 实验代码 main.c usart.c usart.h 一、串口通信 1、概念 串行接口是一种可以将…

Spring 面向切面编程(AOP)

一、aop介绍 (一)前言 一般的后端开发流程是纵向开发,就是controller(控制层)->service(业务层)->mapper(数据持久层),Spring采用动态代理技术可以在…

flstudio21.3.2304高级版水果编曲音乐软件

flstudio高级版是一款适用于广泛领域的音频编辑软件。它支持多通道混音器和VST插件,包括数百种乐器和效果插件。它还为您提供了一个乐谱编辑器,需要对不同乐器的节奏进行必要的编辑。Flstudio具有许多内置电子合成声音,可提供更广泛的电子声音…

基于STM32的四位数码管计数器设计与实现

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进, 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!…