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

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

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

原型模式

概述

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

结构

原型模式包含如下角色

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

实现

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

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有对象地址。
    Java中的Object类中提供了clone()方法来实现浅克隆。
/*** 具体的原型类实现Cloneable接口  这里用Cloneable接口来当做抽象原型类*/
public class RealizeType implements Cloneable{public RealizeType(){System.out.println("使用构造器创建具体的原型对象");};/*** 重写clone()方法* @return RealizeType*/@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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.mzph.cn/news/212635.shtml

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

相关文章

Spring Cloud Gateway + Nacos + LoadBalancer实现企业级网关

1. Spring Cloud Gateway 整合Nacos、LoadBalancer 实现企业级网关 前置工作: 创建 SpringBoot 多模块项目创建网关(gateway-service)、用户(user-service)模块用户模块添加 Nacos discovery 支持以及 Spring Web&am…

gitbash下载安装

参考教程 零、下载 官网地址 2.43.0win64 链接:https://pan.baidu.com/s/16urs_nmky7j20-qNzUTTkg 提取码:7jaq 一、安装 图标组件(Additional icons):选择是否创建桌面快捷方式;桌面浏览(Win…

逸迅科技丁红阳:三种能力帮助企业打造GBI “护城河”

大数据产业创新服务媒体 ——聚焦数据 改变商业 近日,由上海市经济和信息化委员会、上海市科学技术委员会指导,数据猿与上海大数据联盟联合主办的“2023企业数智化转型升级发展论坛”在上海举行。本次论坛以“释放数字价值驱动智能升级”为主题&#xf…

piakachu越权漏洞

水平越权 首先打开这一关,在右侧有一些提示,我们可以看到 然后我们随便输入一组信息即可,可以在url中看到这样的字段 当我们尝试在url中直接更换另一个用户名时可以发现,直接切换到了另一个用户的身份 垂直越权 这里可以看到右边…

一文学会使用 PyInstaller 将 Python 脚本打包为 .exe 可执行文件

文章目录 前言PyInstaller特点跨平台支持自动依赖项处理单文件发布支持图形用户界面(GUI)和命令行界面(CLI)应用支持多种打包选项 基本用法常用参数其它参数 版本 & 环境实现步骤安装 PyInstaller创建 Python 脚本使用 PyInst…

【SpringBoot教程】SpringBoot 创建定时任务(配合数据库动态执行)

作者简介:大家好,我是撸代码的羊驼,前阿里巴巴架构师,现某互联网公司CTO 联系v:sulny_ann(17362204968),加我进群,大家一起学习,一起进步,一起对抗…

transformer模型结构|李宏毅机器学习21年

来源:https://www.bilibili.com/video/BV1Bb4y1L7FT?p4&vd_sourcef66cebc7ed6819c67fca9b4fa3785d39 文章目录 概述seq2seqtransformerEncoderDecoderAutoregressive(AT)self-attention与masked-self attentionmodel如何决定输出的长度…

【亲测有效】支持横竖屏 微信小程序video禁止进度条拖动,微信小程序遮罩进度条,

背景&#xff1a;部分课程禁止客户拖动视频进度条直至播放结束 红色是遮罩区域遮罩区域 实际遮罩效果&#xff08;有一个很浅的阴影区域&#xff09; 实现代码 .wxml文件 <video enable-progress-gesture"false" ><cover-view class"cover">…

基于深度学习的yolov7植物病虫害识别及防治系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介YOLOv7 系统特性工作流程 二、功能三、系统四. 总结 一项目简介 # YOLOv7植物病虫害识别及防治系统介绍 简介 该系统基于深度学习技术&#xff0c;采…

Seata配置

参考教程 seata 分布式事务的环境搭建与使用 Seata 1.4.0 nacos配置和使用&#xff0c;超详细 Seata 1.4.2 的安装 Nacos的配置和使用 官网下载地址 本文以v1.4.1为例 1.数据库及表的创建 创建seata数据库&#xff0c;创建以下表&#xff08;右键连接-》新建数据库seata-》…

windows系统proteus中Ardunio Mega 2560和虚拟机上Ubuntu系统CuteCom进行串口通信

在文章利用proteus实现串口助手和arduino Mega 2560的串口通信-CSDN博客 中&#xff0c;实现了windows系统的proteus中Ardunio Mega 2560和SSCOM通过虚拟串口进行通信。虚拟串口的连接示意图如下图所示。 在文章windows系统和虚拟机上ubuntu系统通过虚拟串口进行通信-CSDN博客…

3DMAX关于显示驱动问题的解决方法大全

3DMAX与显卡驱动有关的问题主要有以下几种情况&#xff1a; 1.3DMAX启动弹出这样的界面&#xff1a; 2.主工具栏按钮不显示&#xff0c;或者鼠标移上去才显示&#xff08;刷新问题&#xff09;。 3&#xff0e;视口菜单不显示或显示不全。 问题分析&#xff1a; 首先&#x…

安全基础从0开始

文章目录 常见名词小实战 网站搭建小实战抓包模拟器状态码返回值网站搭建WEB应用安全漏洞 数据包&封包&信息收集**参考点** 常见名词 前后端&#xff0c;POC/EXP&#xff0c;Payload/Shellcode&#xff0c;后门/Webshell&#xff0c;木马/病毒&#xff0c; 反弹&…

基于ssm应急资源管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本应急资源管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

排序算法之七:归并排序(递归)

基本思想 基本思想&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1…

C++:this指针

目录 前言 成员函数返回this指向的对象本身时&#xff0c;为什是返回引用类型&#xff1f; 成员函数返回this对象本身时&#xff0c;内部通常会通过拷贝构造函数来创建一个临时对象&#xff1f; 总结 前言 c通过提供特殊的对象指针&#xff0c;this指针 指向被调用的成员函…

Nodejs 第二十二章(脚手架)

编写自己的脚手架 那什么是脚手架&#xff1f; 例如:vue-cli Angular CLI Create React App 编写自己的脚手架是指创建一个定制化的工具&#xff0c;用于快速生成项目的基础结构和代码文件&#xff0c;以及提供一些常用的命令和功能。通过编写自己的脚手架&#xff0c;你可以…

Linux和Windows环境下如何使用gitee?

1. Linux 1.1 创建远程仓库 1.2 安装git sudo yum install -y git 1.3 克隆远程仓库到本地 git clone 地址 1.4 将文件添加到git的暂存区&#xff08;git三板斧之add&#xff09; git add 文件名 # 将指定文件添加到git的暂存区 git add . # 添加新文件和修改过的…

vs2017+qt5.14.2遇到的问题

1、在安装qt插件后&#xff0c;导入pro文件时&#xff0c;报 msvc-version.conf loaded but QMAKE_MSC_VER isn’t set 修改E:\Qt\Qt5.14.2\5.14.2\msvc2017_64\mkspecs\common\msvc-version.conf文件中添加

RabbitMQ学习笔记10 综合实战 实现新商家规定时间内上架商品检查

配置文件&#xff1a; 记住添加这个。 加上这段代码&#xff0c;可以自动创建队列和交换机以及绑定关系。 我们看到了我们创建的死信交换机和普通队列。 我们可以看到我们队列下面绑定的交换机。 我们创建一个controller包进行测试: 启动&#xff1a; 过一段时间会变成死信队列…