设计模式【5】-- 原型模式
开局一张图,剩下全靠写...
设计模式文章集合:http://aphysia.cn/categories/designpattern
前言
接触过 Spring
或者 Springboot
的同学或许都了解, Bean
默认是单例的,也就是全局共用同一个对象,不会因为请求不同,使用不同的对象,这里我们不会讨论单例,前面已经讨论过单例模式的好处以及各种实现,有兴趣可以了解一下:http://aphysia.cn/archives/designpattern1。除了单例以外,Spring
还可以设置其他的作用域,也就是scope="prototype"
,这就是原型模式,每次来一个请求,都会新创建一个对象,这个对象就是按照原型实例创建的。
原型模式的定义
原型模式,也是创建型模式的一种,是指用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,简单来说,就是拷贝。一般适用于:
- 实例比较复杂,完全创建成本高,直接复制比较简单
- 构造函数比较复杂,创建可能产生很多不必要的对象
优点:
- 隐藏了创建实例的具体细节
- 创建对象效率比较高
- 如果一个对象大量相同的属性,只有少量需要特殊化的时候,可以直接用原型模式拷贝的对象,加以修改,就可以达到目的。
原型模式的实现方式
一般来说,原型模式就是用来复制对象的,那么复制对象必须有原型类,也就是Prototype
,Prototype
需要实现Cloneable
接口,实现这个接口才能被拷贝,再重写clone()
方法,还可以根据不同的类型来快速获取原型对象。
我们先定义一个原型类Fruit
:
以及拓展了Fruit
类的实体类Apple
,Pear
,Watermelon
:
创建一个获取不同水果类的缓存类,每次取的时候,根据不同的类型,取出来,拷贝一次返回即可:
测试一下,分别获取不同的水果,以及对比两次获取同一种类型,可以发现,两次获取的同一种类型,不是同一个对象:
结果如下:
再测试一下,我们看看里面的name
属性是不是同一个对象:
结果如下,里面的字符串确实还是用的是同一个对象:
这是为什么呢?因为上面使用的clone()是浅拷贝!!!不过有一点,字符串在Java里面是不可变的,如果发生修改,也不会修改原来的字符串,由于这个属性的存在,类似于深拷贝。如果属性是其他自定义对象,那就得注意了,浅拷贝不会真的拷贝该对象,只会拷贝一份引用。
这里不得不介绍一下浅拷贝与深拷贝的区别:
- 浅拷贝:没有真正的拷贝数据,只是拷贝了一个指向数据内存地址的指针
- 深拷贝:不仅新建了指针,还拷贝了一份数据内存
如果我们使用Fruit apple = apple1
,这样只是拷贝了对象的引用,其实本质上还是同一个对象,上面的情况虽然对象是不同的,但是Apple
属性的拷贝还属于同一个引用,地址还是一样的,它们共享了原来的属性对象name
。
那如何进行深拷贝呢?一般有以下方案:
-
直接 new 对象,这个不用考虑了
-
序列化与反序列化:先序列化之后,再反序列化回来,就可以得到一个新的对象,注意必须实现
Serializable
接口。 -
自己重写对象的
clone()
方法
序列化实现深拷贝
序列化实现代码如下:
创建一个Student
类和School
类:
序列化拷贝的类:
测试类:
上面的结果均是false
,说明确实不是同一个对象,发生了深拷贝。
clone实现深拷贝
前面的Student
和School
都实现Cloneable
接口,然后重写clone()
方法:
测试类:
测试结果一样,同样都是false
,也是发生了深拷贝。
总结
原型模式适用于创建对象需要很多步骤或者资源的场景,而不同的对象之间,只有一部分属性是需要定制化的,其他都是相同的,一般来说,原型模式不会单独存在,会和其他的模式一起使用。值得注意的是,拷贝分为浅拷贝和深拷贝,浅拷贝如果发生数据修改,不同对象的数据都会被修改,因为他们共享了元数据。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:Java源码解析
,JDBC
,Mybatis
,Spring
,redis
,分布式
,剑指Offer
,LeetCode
等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。
关注公众号 ”秦怀杂货店“ 可以领取
剑指 Offer V1
版本的C++
解法,敬请期待。
__EOF__

本文链接:https://www.cnblogs.com/Damaer/p/15674723.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库