原型模式 (Prototype Pattern)
定义:
原型模式(Prototype Pattern)是一种创建型设计模式,它用于创建重复的对象,同时保持性能。这种模式的核心思想是通过复制一个已存在的实例来创建新的实例,而不是新建实例并对其进行初始化。原型模式适用于创建复杂对象的情况,特别是当对象创建的成本比较高时,如需要进行繁琐的资源消耗型操作(例如,数据库或文件的读取操作)。
原型模式通常涉及以下几个角色:
- 原型(Prototype):
- 定义用于复制现有对象以生成新对象的接口。
- 具体原型(Concrete Prototype):
- 实现原型接口的类,并提供复制自身的方法。这通常通过实现一个克隆方法(如Java中的
clone()方法)来完成。
- 实现原型接口的类,并提供复制自身的方法。这通常通过实现一个克隆方法(如Java中的
- 客户(Client):
- 创建新的对象时,客户端使用原型实例提供的克隆方法来获取新对象的副本,而不是直接通过
new关键字创建。
- 创建新的对象时,客户端使用原型实例提供的克隆方法来获取新对象的副本,而不是直接通过
解决的问题:
- 高成本的对象创建:
- 当创建一个对象的成本很高时,因为它需要进行复杂的初始化,如从数据库读取数据或进行复杂的计算。原型模式通过复制现有对象来避免这种高成本的创建过程。
- 避免复杂的构造过程:
- 在某些情况下,对象的创建过程可能涉及多个步骤和要求,使用原型模式可以通过直接复制一个已经创建好的实例来简化创建过程。
- 动态添加或删除对象:
- 在运行时动态地添加或删除具有特定配置的对象时,原型模式提供了一种方便的方法来复制配置相同的实例。
- 对象的解耦:
- 有时,系统需要独立于其要创建对象的类。原型模式允许你复制一个对象,而不需要依赖于它们的具体类。
- 优化性能和内存:
- 使用原型模式可以减少系统的整体资源消耗,因为复制通常比创建全新实例更轻量级。
使用场景:
- 性能敏感的对象创建:
- 当对象的创建过程涉及昂贵的数据库操作、文件读取、复杂计算或网络调用等,而复制现有对象的成本相对较低时。
- 避免复杂的初始化步骤:
- 如果一个对象的初始化过程非常复杂,如设置多个字段和依赖,使用原型模式可以通过克隆一个已经初始化的实例来避免这些复杂性。
- 类不容易获取或无法预知:
- 当需要实例化的类在运行时才确定,或者类的实例化过程隐藏在一些我们无法访问的API后面时。
- 动态加载或生成对象:
- 在需要根据当前环境或状态动态生成对象的场景中,可以通过复制预先存储的原型来实现。
- 大量相似对象的场景:
- 当系统需要大量相似对象时,使用原型模式可以避免类初始化时的重复工作。
- 实现对象的解耦:
- 当需要解耦系统中的对象创建和使用时,原型模式允许用户无需知道对象的具体类型就能创建新实例。
示例代码 1 - 浅拷贝实现:
public class ShallowPrototype implements Cloneable {private String name;public ShallowPrototype(String name) {this.name = name;}// getter和setter@Overridepublic ShallowPrototype clone() throws CloneNotSupportedException {return (ShallowPrototype) super.clone();}
}
示例代码 2 - 深拷贝实现:
public class DeepPrototype implements Cloneable {private String name;private SomeComplexObject complexObject;public DeepPrototype(String name, SomeComplexObject complexObject) {this.name = name;this.complexObject = complexObject;}// getter和setter@Overridepublic DeepPrototype clone() throws CloneNotSupportedException {DeepPrototype cloned = (DeepPrototype) super.clone();cloned.complexObject = new SomeComplexObject(this.complexObject); // 创建新的复杂对象实例return cloned;}
}class SomeComplexObject {private String data;public SomeComplexObject(SomeComplexObject obj) {this.data = obj.data;}// getter和setter
}
主要符合的设计原则:
- 开闭原则(Open-Closed Principle):
- 原型模式支持开闭原则。一旦原型对象被创建并实现了克隆(Clone)方法,你可以通过克隆现有对象来添加新的对象实例,而无需修改现有的代码。
- 单一职责原则(Single Responsibility Principle):
- 原型模式允许将对象创建和业务逻辑分离,使得每个类专注于单一的职责。原型对象专注于如何创建和复制自身的实例。
- 里氏替换原则(Liskov Substitution Principle):
- 在原型模式中,任何继承自原型的新对象都应当能替代原型对象。这符合里氏替换原则,即程序中的对象应该能够被其子类对象所替换,而程序的逻辑不受影响。
原型模式主要通过实现开闭原则和单一职责原则来提高代码的可维护性和可扩展性。通过克隆方法,它允许在运行时动态地创建对象,提供了创建对象的灵活方式,同时避免了复杂的构造过程。
在JDK中的应用:
java.lang.Object的clone()方法:- 在Java中,所有类都继承自
java.lang.Object。Object类提供了一个clone()方法,可以用来复制对象。尽管这个方法默认是浅复制,但它提供了实现深复制的基础。
- 在Java中,所有类都继承自
- Java集合框架:
- 许多Java集合类(如
ArrayList,HashSet,HashMap等)实现了Cloneable接口,提供了clone()方法来创建集合的副本。这些集合类的克隆方法通常提供了集合内容的浅复制。
- 许多Java集合类(如
- 日期和时间对象:
- 诸如
java.util.Date这样的日期和时间相关类也实现了Cloneable接口,允许通过克隆方法来创建日期对象的精确副本。
- 诸如
在Spring中的应用:
- Bean的原型作用域:
- 在Spring框架中,Bean的作用域默认是单例(singleton),但可以配置为原型(prototype)。当一个Bean被定义为原型作用域时,每次通过容器请求这个Bean时,Spring容器都会创建一个新的Bean实例,而不是返回一个共享的单例实例。这正是原型模式的应用,即每次需要时都创建一个新的对象副本。
- 解决单例Bean的状态问题:
- 在某些情况下,如果单例Bean包含了可变的数据字段,那么在并发环境下可能会出现数据安全问题。通过将这样的Bean定义为原型作用域,可以为每个请求创建一个新的实例,从而避免了状态共享的问题。
虽然Spring中原型作用域的应用并不广泛,但在需要独立状态或避免共享状态的场景中,原型模式提供了一种有效的解决方案。需要注意的是,与单例Bean相比,原型Bean的生命周期管理、依赖注入和销毁需要更多地由开发者来控制。
相关文章:
原型模式 (Prototype Pattern)
定义: 原型模式(Prototype Pattern)是一种创建型设计模式,它用于创建重复的对象,同时保持性能。这种模式的核心思想是通过复制一个已存在的实例来创建新的实例,而不是新建实例并对其进行初始化。原型模式适…...
项目总结报告(案例模板)
软件项目总结报告模板套用: 项目概要项目工作分析经验与教训改进建议可纳入的项目过程资产 --------进主页获取更多资料-------...
C++ Qt QByteArray用法介绍
作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 一、QByteArray的基本用法1、初始化和赋值2、访问和修改元素3、 常用方法4、数据转换二、QByteArray与文件操作三、QByteArray与网络编程四、QByteArray数据编码1、Base64 编解…...
蓝桥杯物联网竞赛_STM32L071_3_Oled显示
地位: 对于任何一门编程语言的学习,print函数毫无疑问是一种最好的调试手段,调试者不仅能通过它获取程序变量的运行状态而且通过对其合理使用获取程序的运行流程,更能通过关键变量的输出帮你验证推理的正确与否,朴素的…...
python-opencv轮廓检测(外轮廓检测和全部轮廓检测,计算轮廓面积和周长)
python-opencv轮廓检测(外轮廓检测和全部轮廓检测,计算轮廓面积和周长) 通过cv2.findContours,我们可以进行轮廓检测,当然也有很多检测模式,我们可以通过选择检测模式,进行外轮廓检测ÿ…...
LeetCode [简单] 1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...
C++设计模式之工厂模式(下)——抽象工厂模式
抽象工厂模式 介绍示例示例使用运行结果抽象工厂模式的优缺点优点缺点 总结 介绍 抽象工厂模式是一种创建型设计模式,它提供了一种封装一组相关或相互依赖对象的方式,而无需指定它们具体的类。它允许客户端使用抽象接口来创建一系列相关的对象ÿ…...
2023亚太杯数学建模A题思路分析 - 采果机器人的图像识别技术
1 赛题 问题A 采果机器人的图像识别技术 中国是世界上最大的苹果生产国,年产量约为3500万吨。与此同时,中国也是世 界上最大的苹果出口国,全球每两个苹果中就有一个,全球超过六分之一的苹果出口 自中国。中国提出了一带一路倡议…...
关于Flink的旁路缓存与异步操作
1. 旁路缓存 1. 什么是旁路缓存? 将数据库中的数据,比较经常访问的数据,保存起来,以减少和硬盘数据库的交互 比如: 我们使用mysql时 经常查询一个表 , 而这个表又一般不会变化,就可以放在内存中,查找时直接对内存进行查找,而不需要再和mysql交互 2. 旁路缓存例子使用 dim层…...
MyBatis-Plus的分页插件和乐观锁插件
MyBatis-Plus: 探索分页查询和乐观锁插件 在现代的Web应用开发中,高效的数据处理是不可或缺的一部分。MyBatis-Plus,作为MyBatis的增强版,提供了多种插件来简化和优化数据库操作。在这篇博客中,我们将重点介绍两个非常实用的插件…...
批量将本地N个英文Html文档进行中文翻译-操作篇
Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…...
解决cad找不到vcruntime140.dll的方法,实测有效的5个的方法
最近,我在使用CAD软件时遇到了一个困扰我已久的问题:由于找不到vcruntime140.dll文件而导致CAD无法正常运行。经过一番努力和尝试,我终于找到了解决这个问题的方法。那么,如何解决vcruntime140.dll丢失的问题呢?本文将…...
2023亚太杯数学建模C题:我国新能源电动汽车的发展趋势,思路模型代码
问题C 我国新能源电动汽车的发展趋势 赛题思路:获取思路见文末名片,第一时间更新 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源( 非常规汽车燃料指汽油、柴油以外的燃料),将先进技术进行汽车动力控制…...
英语学习-爆破音
英文爆破音有:[p],[b],[t],[d],[k],[g]。 同时爆破音的发音会根据前后音的不同,发音不同,具体如下: ⒈ [p],[b],[t],[d],[k],[g] 中的任何两个音素相邻时,前面的发不完全爆破音,后面的就要完全地爆破。如…...
【Vue】图片切换
上一篇: vue的指令 https://blog.csdn.net/m0_67930426/article/details/134599378?spm1001.2014.3001.5502 本篇所需要的指令有: v-on v-bind v-show <!DOCTYPE html> <html lang"en"> <head><meta charset"…...
C++模拟如何实现vector的方法
任意位置插入,insert的返回值为新插入的第一个元素位置的迭代器;因为插入可能会进行扩容,导致start的值改变,所以先定义一个变量保存pos与start的相对位置;判断是否需要扩容;从插入位置开始,将所…...
芯知识 | 混音播报语音芯片的优势:革新音频应用的新力量
随着科技的进步,语音芯片在各个领域的应用越来越广泛。而在众多语音芯片中,混音播报语音芯片以其独特的优势,正逐渐成为音频应用领域的翘楚。本文将重点探讨混音播报语音芯片的优势及其在现代科技应用中的价值。 一、混音播报语音芯片概述 …...
Arduino驱动PT100数字K型高温传感器(温湿度传感器)
目录 1、传感器特性 2、控制器和传感器连线图 3、硬件原理图 4、驱动程序 PT100适用于大部分400℃以下高温的测量,但是通常家用天然气灶焰芯温度可达800℃以上,烧制陶瓷的窖子或者大功率电炉温度更可超过1000℃,在这些超高温度的场景下就需要用到K型热电偶。...
【C/PTA —— 11.函数2(课外实践)】
C/PTA —— 11.函数2(课外实践) 一.函数题6-1 计算A[n]1/(1 A[n-1])6-2 递归实现顺序输出整数6-3 自然数的位数(递归版)6-4 分治法求解金块问题6-5 汉诺塔6-6 重复显示字符(递归版)6-7 显示平行四边形(右)(递归版) 二.编程题7-2 N阶楼梯上楼问题 一.函数…...
2023 Unite 大会关于“Muse“ AI 大模型训练
Unity Muse 借助强大的 AI 能力帮助你探索、构思和迭代,其中包括纹理和精灵两项功能,可将自然语言和视觉输入转化为可用资产。 将 AI 引入 Unity Editor 中的 Muse 提供了更快将想法转化为实物的选项。您可以调整并使用文本提示、图案、颜色和草图&…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
