23种设计模式(3) java原型模式
23种设计模式第三篇:java原型模式
定义:
通过复制现有的对象实例来创建新的对象实例。
实现:
实现Cloneable接口:
Cloneable接口的作用是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
重写Object类中的clone方法:
Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,原型类需要将clone方法的作用域修改为public类型。
示例:
例如,对于拿邮件发邀请函,邮件类大部分内容都是一样的:邀请原由、相邀地点,相聚时间等等,但对于被邀请者的名称和发送的邮件地址是不同的。
定义Mail类:
public class Mail implements Cloneable { private String receiver; private String subject; private String content; private String tail; public Mail(EventTemplate et) { this.tail = et.geteventContent(); this.subject = et.geteventSubject(); } @Override public Mail clone() { Mail mail = null; try { mail = (Mail) super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return mail; } //get、set..... }
测试方法:
public static void main(String[] args) { int i = 0; int MAX_COUNT = 10; EventTemplate et = new EventTemplate("邀请函(不变)", "婚嫁生日啥的....(不变部分)"); Mail mail = new Mail(et); while (i < MAX_COUNT) { Mail cloneMail = mail.clone(); cloneMail.setContent("XXX先生(女士)(变化部分)" + mail.getTail()); cloneMail.setReceiver("每个人的邮箱地址...com(变化部分)"); sendMail(cloneMail); i++; } }
优点:
1、使用原型模型创建一个对象比直接new一个对象更有效率,因为它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
2、隐藏了制造新实例的复杂性,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
缺点:
1、由于使用原型模式复制对象时不会调用类的构造方法,所以原型模式无法和单例模式组合使用,因为原型类需要将clone方法的作用域修改为public类型,那么单例模式的条件就无法满足了。
2、使用原型模式时不能有final对象。
3、Object类的clone方法只会拷贝对象中的基本数据类型,对于数组,引用对象等只能另行拷贝。这里涉及到深拷贝和浅拷贝的概念。
深拷贝与浅拷贝:
浅拷贝:
将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的(这样不安全)。
深拷贝:
将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。
那么深拷贝如何具体实现呢?
继续上面的例子,增加了一个ArrayList属性。
private String receiver; private String subject; private String content; private String tail; private ArrayList<String> ars;
此时,单mail = (Mail) super.clone();无法将ars指向的地址区域改变,必须另行拷贝:
try { mail = (Mail) super.clone(); mail.ars = (ArrayList<String>)this.ars.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
适用场景:
1、复制对象的结构和数据。
2、希望对目标对象的修改不影响既有的原型对象。
3、创建一个对象的成本比较大。
转自:java知音
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Selenium+Tesseract-OCR智能识别验证码爬取网页数据的实例
本文主要介绍了Selenium+Tesseract-OCR智能识别验证码爬取网页数据,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2021-09-09idea64.exe.vmoptions文件如何设置调整VM配置文件
这篇文章主要介绍了idea64.exe.vmoptions文件如何设置调整VM配置文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-04-04maven安装、使用、配置本地仓库、idea配置maven以及解决plugins报错问题
本地仓库是远程仓库的一个缓冲和子集,当你构建Maven项目时首先会从本地仓库查找资源,如果没有那么Maven会从远程仓库下载到你本地仓库,这篇文章主要给大家介绍了关于maven安装、使用、配置本地仓库、idea配置maven以及解决plugins报错问题的相关资料,需要的朋友可以参考下2024-01-01SpringBoot集成Flink-CDC实现对数据库数据的监听问题
Flink CDC(Flink Change Data Capture)是一种基于数据库日志的CDC技术,它实现了一个全增量一体化的数据集成框架,这篇文章主要介绍了SpringBoot集成Flink-CDC,实现对数据库数据的监听,需要的朋友可以参考下2024-07-07spring schedule配置多任务动态cron(增删启停)
这篇文章主要介绍了spring schedule配置多任务动态cron(增删启停),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-03-03
最新评论