5、设计模式之原型模式(Prototype)

news/2024/5/25 9:36:48/文章来源:https://blog.csdn.net/weixin_45817985/article/details/136642852

一、什么是原型模式
原型模式属于创建型设计模式。通过复制现有的实例来创建新的实例,无需知道相应类的信息。

简单的讲就是当我需要创建一个指定的对象时,刚好现在就有这个对象,但又不能直接使用,所以简单的方式就是克隆一个一摸一样的对象来使用。

二、角色组成

抽象原型类(Prototype):定义了一个抽象的克隆方法。
具体原型类(ConcretePrototyoe):实现抽象原型类(接口)定义的克隆方法,提供一个具体的克隆方法来复制自己。
客户端(Client):使用原型类的对象来实现具体的操作,即通过复制原型对象来创建新的对象。

三、优缺点

优点:

提高了对象创建的效率,在创建大量对象时可以节省时间和资源; 可以隐藏对象创建和初始化的复杂性,并且更容易管理和维护;
可以在运行时动态添加和删除对象; 可以保护原始对象,防止意外修改对原对象产生影响。
缺点:

必须保证原始对象和克隆对象之间的区别,否则可能会产生副作用; 有些对象可能无法进行有效地复制,例如涉及到与其他外部对象交互的对象;
原型模式需要给对象添加一个克隆方法。但是,该方法可能不适用于所有对象类型,例如具有命令行参数的程序。

四、应用场景
4.1 生活场景

克隆羊多利
细胞分裂
孙悟空的七十二变

4.2 java场景

Object类:Java中的所有类都直接或间接继承自Object类,它提供了一个clone()方法,允许对象在克隆时使用它们的原型对象。
Collection框架:Iterator接口使用原型模式来提供多个访问数据的独立副本(例如ListIterator和Enumeration)。这种方式可以确保迭代器始终指向正确的位置。
Apache Commons BeanUtils:Apache Commons
BeanUtils库采用了原型模式的方法,通过使用BeanUtils.cloneBean()方法来创建新对象并通过复制其属性来克隆一个Bean。
Spring框架:在Spring框架中,原型范围bean使用原型模式。例如,在Spring中,可以将作用域设置为prototype,来创建一个bean的多个独立实例,这样每次在容器中注入bean时,将创建新的实例。

五、代码实现
下面以英雄联盟塞拉斯窃取其他英雄大招为例。

5.0 UML类图
在这里插入图片描述
5.1 HeroSkill(英雄–具体原型类)
定义一个具体原型类(HeroSkill),也就是被窃取技能的英雄,实现了Cloneable接口(抽象原型类)。

/*** * 具体的原型类,被窃取技能的英雄*/
public class HeroSkill implements Cloneable{private String name;private String bigMove;public HeroSkill(){}public HeroSkill(String name, String bigMove){this.name=name;this.bigMove=bigMove;}@Overridepublic HeroSkill clone() {HeroSkill clone= null;try {clone = (HeroSkill) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}System.out.println("塞拉斯窃取"+name+"的大招:"+bigMove);return clone;}//英雄的大招展示public void showSkill() {System.out.println(name+"的大招:"+bigMove);}
}

5.2 StealManFactory(塞拉斯–客户端)
塞拉斯工厂客户端,用于复制对象(英雄)

/*** * 工厂类,用于在客户端中复制对象* (塞拉斯,窃取别的英雄技能)*/
public class StealManFactory {private HeroSkill heroSkill;public StealManFactory(HeroSkill heroSkill){this.heroSkill=heroSkill;}public void setHeroSkill(HeroSkill heroSkill){this.heroSkill=heroSkill;}public HeroSkill cloneHeroSkill(){return heroSkill.clone();}
}

5.3 TestPrototype

/*** * 原型模式*/
@SpringBootTest
public class TestPrototype {@Testvoid testPrototype(){//初始化英雄HeroSkill heroSkill=new HeroSkill("盲僧","神龙摆尾");//初始化工厂类(塞拉斯)StealManFactory factory=new StealManFactory(heroSkill);//复制英雄技能HeroSkill cloneHeroSkill = factory.cloneHeroSkill();//塞拉斯复制的技能cloneHeroSkill.showSkill();System.out.println("-------下方原英雄技能展示----------");//原英雄技能heroSkill.showSkill();}
}

六、总结
适用于开发的场景:

如果一个对象的创建过程包括繁琐的准备工作或重量级的资源初始化,那么每次需要创建新对象时,都需要必须执行这些初始操作,这时就可以使用原型模式,通过复制旧对象来创建新对象,从而避免创建成本高的问题。
如果对象需要修改的属性较多,使用原型模式则可以在原始对象的基础上进行修改,减少代码量。
如果存在多个对象需要共享同一个数据源,可以使用原型模式基于已有的原始对象来进行克隆,避免了重复创建多个对象。
当对象的创建过程涉及多个线程时,需要注意线程安全性。原型模式可以用于在不同的线程之间共享原型对象,并在每个线程中创建对象的副本,确保线程安全性。
在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。

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

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

相关文章

【阿里云系列】-基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户,我们通常会选择CICD工具来减少人力投入产生的成本,开源的工具比如有成熟的Jenkins,但是本文讲的是阿里云提高的解决方案云效平台,通过配置流水线的形式实现项目的快速部署到服务器…

Golang入门简介与基本语法学习

简介 Golang的出现背景 Go语言,或我们通常称之为Golang,它的设计哲学深受其创造者的软件开发经验影响,它旨在实现快速编译、高性能、静态类型检查以及简洁明了的代码风格。 是由Google开发的一个开源编程语言,它首次公布于2009…

Qt(C++) | QPropertyAnimation动画(移动、缩放、透明)篇

动画类继承关系图 # QPropertyAnimation QPropertyAnimation是一个可以在Qt应用程序中使用的动画框架。它可以用于创建各种动画效果,包括但不限于以下几种: 1. 移动动画:可以将一个对象从一个位置平滑地移动到另一个位置。比如,你可以创建一个按钮,当用户点击它时,按钮…

短视频解析接口分发系统

宝塔面板:Nginx系统 php7.2 Mysql 5.6-5.7 伪静态Thinkphp 上传文件直接访问域名安装即可 可以自备 听说后边要出saas去水印小程序 下载地址:https://pan.xunlei.com/s/VNskSEelfRVIzoSm5P5Rcw34A1?pwdqzhh# 接口演示: 前端演示…

王道机试C++第 5 章 数据结构一:向量vector和蓝桥杯13年两个程序 Day31

5.1 向量 有限个类型相同的变量的线性集合,组成数组的各个变量称为数组的元素。给每个元素分配唯一的一个下标,就能用这个下标指代该元素。还可通过下标直接访问数组中的任何一个元素,并且这些访问能在常数时间内完成。 1.STL-v…

TortoiseSVN 报错:The server unexpectedly closed the connetion

前言 CentOS7Linux 安装subversionmod_dav_svn,搭建subversion(svn)服务器 The server unexpectedly closed the connetion 解决办法 重启Apache服务 shell> systemctl restart httpd

【Ubuntu】将多个python文件打包为.so文件

1.为什么要将python打包为.so文件? 保护源码 2.实战例子 a.安装相应的包 pip install cython 验证安装是否成功 cython --version b.实战的文件目录和内容 hi.py # This is a sample Python script.# Press ShiftF10 to execute it or replace it with your…

安装包逆向1

1.找到程序的入口点 在IDA中我们看到函数非常多,但是一般都是有主要的入口的,所以找一下有没有主函数 可以直接 CtrF直接查找 CNsInstaller::CNsInstaller 这里搞半天在获取文件路径 CNsInstaller::StartInstall CNsInstaller::InstallFunc char…

苍穹外卖学习-----2024/03/010---redis,店铺营业状态设置

1.Redis入门 2.在Java中操作Redis 3.店铺营业状态设置 BUG!!! 今天在启动项目时,用到了Redis缓存数据库,但是却出现了报错信息: ERR Client sent AUTH, but no password is set。Caused by: io.lettuce.core.RedisCommandExecutionException…

面试经典150题【71-80】

文章目录 面试经典150题【71-80】112.路径总和129.求根节点到叶子节点的数字之和124.二叉树中的最大路径和(要思考)173.二叉树迭代搜索器222.完全二叉树节点的个数236.二叉树的最近公共祖先199.二叉树的右视图637.二叉树的层平均值102.二叉树的层序遍历1…

9、组合模式(结构性模式)

组合模式又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构,以一致的方式处理叶子对象以及组合对象,不以层次高低定义类,都是结点类 一、传统组合模式 举例,大学、学院、系,它们…

guava的使用

对数组操作前判断是否会越界&#xff1a; List<String> s new ArrayList<>();System.out.println(Preconditions.checkElementIndex(2,s.size(),"下标长度超过了")); 是否为空 String s null;System.out.println(Preconditions.checkNotNull(s)); 判空…

设计模式学习系列 -- 随记

文章目录 前言 一、设计模式是什么&#xff1f; 二、设计模式的历史 三、为什么以及如何学习设计模式&#xff1f; 四、关于模式的争议 一种针对不完善编程语言的蹩脚解决方案 低效的解决方案 不当使用 五、设计模式分类 总结 前言 最近可能工作生活上的稳定慢慢感觉自己丢失…

小米公司研发岗的年终奖。。

小米 好的公司有年终且在年前发放&#xff0c;一般的公司有&#xff08;可能打折的&#xff09;年终且年后分批发放&#xff0c;不好的公司各有操作。 3 月已来&#xff0c;小米的年终也开始热议起来。 最近&#xff0c;一则「传小米年终打折&#xff0c;14薪能保住吗」冲上热搜…

修改dataV-vue3 中的组件 装饰5 decoration5 的动画重复次数

dataV-vue3 文档 装饰 5 是一个具有动画效果的 背景线框 但是开发者 没有给我们 提供 动画重复次数的 配置项&#xff0c;只提供了单次动画时长&#xff0c;如果把单词动画时长设置的很长&#xff0c;动画的延展速度也会跟着变得很慢&#xff0c;不符合预期。 使用开发者工具…

学习vue3第五节(reactive 及其相关)

1、定义 reactive() 创建一个响应式代理对象&#xff0c;不同于ref()可以创建任意类型的数据&#xff0c;而reactive()只能是对象&#xff0c;会响应式的深层次解包任何属性&#xff0c;将其标注为响应式 响应式是基于ES6的proxy实现的代理对象&#xff0c;该proxy对象与原对象…

rtthread stm32h743的使用(七)dac设备使用

我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验&#xff0c;核心板如图&#xff1a; 1.我们还是先建立工程 2.生成工程后打开mx进行配置&#xff0c;时钟配置如前所讲&#xff0c;不在赘述 3.更改mx文件…

Vue3全家桶 - Vue3 - 【8】模板引用【ref】(访问模板引用 + v-for中的模板引用 + 组件上的ref)

模板引用【ref】 Vue3官网-模板引用&#xff1b;如果我们需要直接访问组件中的底层DOM元素&#xff0c;可使用vue提供特殊的ref属性来访问&#xff1b; 一、 访问模板引用 在视图元素上采用ref属性来设置需要访问的DOM元素&#xff1a; 该 ref 属性可采用 字符串 值的执行设…

浏览器的工作原理

从输入一个url到页面加载完成&#xff0c;中间都发生了什么&#xff1f; 参考原文地址 首先在浏览器地址栏输入一个地址并回车之后&#xff0c; 1. DNS查找 浏览器会进行DNS查找&#xff0c;把域名https://example.com转化为真实的IP地址10.29.33.xx&#xff0c;根据IP地址找…

Linux——权限的理解

Linux——权限的理解 文章目录 Linux——权限的理解一、shell命令以及运行原理二、Linux权限的概念切换用户对指令提权 三、Linux权限管理1. 文件访问者的分类&#xff08;人&#xff09;2. 文件类型和访问权限&#xff08;事物属性&#xff09;文件类型基本权限文件权限值的表…