设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
文章目录
- 设计模式概述
- 1、原型模式
- 2、原型模式的使用场景
- 3、优点
- 4、缺点
- 5、主要角色
- 6、代码示例
- 7、总结
- 题外话关于使用序列化实现深拷贝
设计模式概述
创建型模式:工厂方法、抽象方法、建造者、原型、单例。
结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。
行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。
常用设计模式:
单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。
1、原型模式
- 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。
- 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。
2、原型模式的使用场景
- 在需要一个类的大量对象的时候,使用原型模式是最佳选择,因为原型模式是在内存中对这个对象进行拷贝,要比直接new这个对象性能要好很多,在这种情况下,需要的对象越多,原型模式体现出的优点越明显。
- 如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算,那么可以使用原型模式。
- 当需要一个对象的大量公共信息,少量字段进行个性化设置的时候,也可以使用原型模式拷贝出现有对象的副本进行加工处理。
3、优点
- 原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间,由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。
4、缺点
- 原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候。
5、主要角色
(1)客户(Client)角色:客户类提出创建对象的请求。
(2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
(3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
6、代码示例
1)UML图

2)源代码
(1)抽象原型角色
public interface Prototype{/*** 克隆自身的方法* @return 一个从自身克隆出来的对象*/public Object clone();
}
(2)具体原型角色
public class ConcretePrototype1 implements Prototype {public Prototype clone(){//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了Prototype prototype = new ConcretePrototype1();return prototype;}
}public class ConcretePrototype2 implements Prototype {public Prototype clone(){//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了Prototype prototype = new ConcretePrototype2();return prototype;}
}
(3)客户端角色
public class Client {public static void main(String[]args){try{Prototype p1 = new ConcretePrototype1();//获取原型来创建对象Prototype p2 = p1.clone();//有人动态的切换了实现Prototype p3 = new ConcretePrototype2();Prototype p4 = p3.clone();}catch(Exception e){e.printStackTrace();}}
}
}
7、总结
- 这种情况就是浅拷贝,java只拷贝你指定的对象,至于你指定的对象里面的别的对象,它不拷贝,还是把引用给你,共享变量,这是一种非常不安全的方式,需要特别注意。
- 内部的数组和引用对象不会拷贝,其他的原始基本类型和String类型会被拷贝。
- 如果需要可以使用深拷贝,结合具体对象的情况进行处理(可以自己实现深拷贝逻辑;或者利用序列化和反序列化实现深拷贝,前提是所有需要复制的对象都需要实现java.io.Serializable接口。)
题外话关于使用序列化实现深拷贝
利用序列化实现深度克隆:
- 把对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。
- 在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。
public Object deepClone() throws IOException, ClassNotFoundException{//将对象写到流里ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//从流里读回来ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return ois.readObject();}
-
这样做的前提就是对象以及对象内部所有引用到的对象都是可序列化的,否则,就需要仔细考察那些不可序列化的对象可否设成transient,从而将之排除在复制过程之外。
-
浅度克隆显然比深度克隆更容易实现,因为Java语言的所有类都会继承一个clone()方法,而这个clone()方法所做的正式浅度克隆。
相关文章:
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
文章目录 设计模式概述1、原型模式2、原型模式的使用场景3、优点4、缺点5、主要角色6、代码示例7、总结题外话关于使用序列化实现深拷贝 设计模式概述 创建型模式:工厂方法、抽象方法、建造者、原型、单例。 结构型模式有:适配器、桥接、组合、装饰器、…...
Study-Oracle-10-ORALCE19C-RAC集群维护
一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。 一、RAC的逻辑架构与进程 1、RAC 与单实例进程的对比 2、RAC相关进程功能 3、在主机查看RAC进程 其他的不列举了 4、RAC集群启停命令 检查集群状态 ORACLE 19C …...
【无题】夜入伊人笑愉,泪湿心夜难眠。
在这句诗中,意境描绘了一种深沉的情感体验,充满了温柔与哀愁。诗人通过“夜入伊人笑愉”开启了一段梦境之旅,其中“夜入”象征着进入梦境的状态。在这个梦幻的世界里,诗人与心爱的人欢笑嬉戏,那份快乐和亲昵如同真实的…...
docker下载mysql时出现Unable to pull mysql:latest (HTTP code 500) server error 问题
报错 Unable to pull mysql:latest (HTTP code 500) server error - Get “https://registry-1.docker.io/v2/”: EOF 解决方法 将VPN开到Global模式 解决啦...
厦门网站设计的用户体验优化策略
厦门网站设计的用户体验优化策略 在信息化快速发展的今天,网站作为企业与用户沟通的重要桥梁,用户体验(UX)的优化显得尤为重要。尤其是在交通便利、旅游资源丰富的厦门,吸引了大量企业进驻。在这样竞争激烈的环境中&am…...
Fastjson反序列化
Fastjson反序列化一共有三条利用链 TempLatesImpl:实战中不适用JdbcRowSetImpl:实际运用中较为广泛BasicDataSource(BCEL) 反序列化核心 反序列化是通过字符串或字节流,利用Java的反射机制重构一个对象。主要有两种…...
Python Linux解压安装脚本
本脚本用于安装python3.x, 需要指定python版本,如12代表3.12 安装文件下载自 python-build-standalone 我下载的文件后缀是:-x86_64-unknown-linux-gnu-pgo-full.tar.zst,根据需要自行下载 注意:install_only或tar.gz包的目录没有…...
numpy 逻辑运算方法介绍
在 NumPy 中,逻辑运算方法用于对数组中的元素进行逻辑操作,通常用于布尔数组,也可用于数值数组,非零值视为 True,零值视为 False。常见的逻辑运算方法有: 1. numpy.logical_and 逐元素进行逻辑与运算&…...
怎么查看网站是否被谷歌收录,查看网站是否被谷歌收录的简便方法
查看网站是否被谷歌收录,有多种简便方法可供选择。以下是一些常用的简便方法: 一、使用“site:”指令 打开谷歌搜索引擎: 在浏览器中打开Google.com,确保使用的是谷歌的官方搜索引擎。 输入查询指令: 在搜索框中输…...
【前端开发入门】前端开发环境配置
目录 引言一、Vscode编辑器安装1. 软件下载2. 软件安装3. 插件安装 二、Nodejs环境安装及版本控制1. 安装内容2. 使用nvm安装2.1 软件下载并安装2.2 nvm基本指令2.3 nvm下载过慢导致超时解决 三、git安装及配置1. 软件下载2. 软件安装3. 基础配置 四、总结 引言 本系列教程旨在…...
Windows驱动开发(二)
1. NT和WDM式驱动 1. NT式驱动 传统的Windows系统驱动类型。NT式驱动的启动/停止/安装/卸载只能由 服务控制管理程序组件(SCM) 来完成的。 包括最简单的hello world,以及目前常用的文件过滤框架 minifilter 都是基于NT式实现的。 NT式驱动的最大特点即完全不依赖硬…...
Hotspot是什么?
Hotspot 简单来说,JVM的一种。 一、HotSpot 的官方定义 HotSpot 是 Oracle 公司开发的一个高性能的 Java 虚拟机(JVM)。它通过一系列先进的技术和优化手段,为 Java 应用程序提供高效的运行环境,实现了跨平台的代码执行…...
k8s-集群部署1
k8s-集群部署1 一、基础环境准备二、docker环境准备三、k8s集群部署1.kubeadm创建集群2.使用kubeadm引导集群 总结 一、基础环境准备 首先,需要准备三个服务器实例,这里我使用了阿里云创建了三个实例,如果不想花钱,也可以在VM上创…...
wordpress Contact form 7发件人邮箱设置
此教程仅适用于演示站有留言的主题,演示站没有留言的主题,就别往下看了,免费浪费时间。 使用了Contact form 7插件的简站WordPress主题,在有人留言时,就会发邮件到网站的系统邮箱(一般与管理员邮箱为同一个)里。上面显…...
15分钟学 Python 第38天 :Python 爬虫入门(四)
Day38 : Python爬虫异常处理与反爬虫机制 章节1:异常处理的重要性 在爬虫开发过程中,网络请求和数据解析常常会遭遇各种异常。正确的异常处理可以提高程序的稳定性,避免崩溃,并帮助开发者快速定位问题。 章节2:常见…...
GWAS分析中显著位点如何注释基因:excel???
大家好,我是邓飞。 今天星球的小伙伴问了一个问题: 我现在在做GWAS分析,现在已经找到性状关联的SNP位点,下一步我如何根据position 找到基因呢? 关于基因注释,之前写过一些博客,可以用到的软件…...
深入浅出 CSS 定位:全面解析与实战指南
“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 目录 前言文章有误敬请斧正 不胜感恩!1. CSS 定位概述2. 定位类型详解2.1 static(默认定位)2.2 relative(相对定位)2.3 absolute(绝对定位&am…...
HTTPS协议详解:从原理到流程,全面解析安全传输的奥秘
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storm…...
Android 13.0 系统内存优化之修改dalvik虚拟机的内存参数
1.前言 在13.0的系统rom开发定制中,app应用也是运行在dalvik虚拟机上的,所以对于一些内存低的系统中,在某些大应用会出现耗内存 卡顿情况,这是系统分配的内存不够大,在进行耗内存的操作,就会出现频繁gc等等原因造成不流畅的现象,接下来就分析下 虚拟机分配内存的相关原理…...
C# 无边框窗体,加阴影效果、多组件拖动、改变大小等功能完美实现优化版效果体验
一、预览效果 国庆节第一天,祝祖国繁荣昌盛! 1.1 效果图 (WinForm无边框窗体,F11可全屏) 拖动窗体时半透明效果(拖动时参考窗体后面释放位置) 说明:本功能的实现基于网友的原型完善而来,更多代码可以参考他的文章 h...
Ubuntu 20.04 下 Zotero 文献管理神器:从安装到插件配置的完整避坑指南
Ubuntu 20.04 下 Zotero 文献管理神器:从安装到插件配置的完整避坑指南 第一次在Linux环境下配置文献管理工具时,我盯着终端里密密麻麻的命令行输出,突然意识到学术研究的数字化工具链竟如此脆弱。直到遇见Zotero,这款跨平台的开源…...
Winhance中文版:让Windows系统管理不再复杂的全能工具
Winhance中文版:让Windows系统管理不再复杂的全能工具 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh…...
告别虚拟机!Windows WSL2+GNU Radio玩转HackRF-One无线接收(避坑指南)
告别虚拟机!Windows WSL2GNU Radio玩转HackRF-One无线接收(避坑指南) 在软件定义无线电(SDR)领域,HackRF-One因其开源设计和亲民价格成为入门首选。然而传统虚拟机方案常因性能损耗、驱动兼容性问题让新手望…...
避坑指南:通达信DLL加密常见的5大误区与替代方案
通达信指标加密实战:5种DLL开发陷阱与零代码解决方案 在量化交易领域,指标公式的保护一直是开发者面临的棘手问题。最近三个月内,某金融开发者社区关于"通达信DLL加密失败"的求助帖增长了47%,暴露出传统加密方案存在显…...
《数据驱动防折叠:利用企微API与数据分析平台构建智能发送决策系统》
一、问题背景企微群发折叠与用户的历史互动行为紧密相关。对长期未交互的用户发送营销内容,折叠概率极高;而对活跃用户发送相似内容,则可能正常显示。因此,单纯从发送端进行策略优化是不够的,必须引入用户维度的数据&a…...
docker部署jar包的几种方式
docker部署jar包的几种方式前言使用Dockerfile手动打包jarDockerfile可复用容器jdk镜像直接创建可复用容器maven插件打包maven打包自动推送镜像到指定服务器关于docker容器启动后注册到nacos的ip是docker容器ip问题!总结前言 简单记录一下docker打包jar部署的几种方…...
Metro性能监控终极指南:如何快速分析和优化React Native打包构建过程
Metro性能监控终极指南:如何快速分析和优化React Native打包构建过程 【免费下载链接】metro 🚇 The JavaScript bundler for React Native 项目地址: https://gitcode.com/gh_mirrors/me/metro Metro作为React Native的官方JavaScript打包工具&a…...
3分钟搭建免费B站视频解析服务:零基础教程
3分钟搭建免费B站视频解析服务:零基础教程 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse 你是否曾经想要保存B站的精彩视频却不知道如何操作?或者需要在自己的网站上嵌入B站视…...
突破性AMD Ryzen硬件调试方案:SMUDebugTool深度解析与实战指南
突破性AMD Ryzen硬件调试方案:SMUDebugTool深度解析与实战指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: ht…...
Linux网络命名空间实战:5分钟搞定veth pair跨命名空间通信
Linux网络命名空间实战:5分钟搭建隔离通信环境 在云计算和容器化技术蓬勃发展的今天,Linux网络命名空间已经成为系统管理员和开发者的必备技能。想象一下,当你需要在单台物理机上同时运行多个需要独立网络环境的服务时,传统方式可…...
