设计模式之-原型模式(三妻四妾)

简介:   原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。我们在程序设计的时候通常会创建很多对象,并且随着不断地开发,会发现在使用过程很多对象是相似甚至是相同的,如果没有使用原型模式,那么我们需要进行下面类似的操作(翻出以前的代码),大量的set方法,这代码看起来十分的“工整”,“干净”,但是全部是无脑式的体力劳动,没有半点技术含量,这种方式不仅浪费了大量的时间去写,其效率还不高,因为需要进行对象的初始化,还要一个一个的赋值,原型模式就是为了来解决这种无脑式的操作。

介绍


  原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。我们在程序设计的时候通常会创建很多对象,并且随着不断地开发,会发现在使用过程很多对象是相似甚至是相同的,如果没有使用原型模式,那么我们需要进行下面类似的操作(翻出以前的代码),大量的set方法,这代码看起来十分的“工整”,“干净”,但是全部是无脑式的体力劳动,没有半点技术含量,这种方式不仅浪费了大量的时间去写,其效率还不高,因为需要进行对象的初始化,还要一个一个的赋值,原型模式就是为了来解决这种无脑式的操作。 



  想必克隆这个词我们大家都很熟悉,1996年在英国爱丁堡市罗斯林研究所克隆出了世界上第一个克隆生物-克隆羊多利,我们的原型模式也是运用了克隆这个思想,下面我们都将其称为拷贝,原型模式就是通过拷贝原型对象,然后再创建出一个同拷贝对象一样的对象(但是它们并不是同一个对象,只是类型相同罢了),只不过他不是通过对象的构造函数进行赋值而来的,而是基于内存的二进制流进行复制,所以效率比new一个对象进行复制要高效。


  Java为我们内置了原型接口(Cloneable),如果要进行对象的拷贝,必须实现Cloneable接口,它是一个空接口,里面没有任何的方法,它只是一个规约而已,我们实现Cloneable接口只需要在类里面重写Object的clone()方法,这样我们就可以进行对象的拷贝,注意:如果没有实现Cloneable接口,直接使用Object的clone()方法,那么将会抛出异常(CloneNotSupportedException),因为JVM里面识别该类没有实现Cloneable接口,不能安全的进行拷贝,我们看一下它们的实现关系 



  下面我们进行实际的操作:


  假如我有一个女朋友,她的身高170cm,体重55kg,胸围90,人长得漂亮,就是不太温柔,因为和她在一起的时间的长了,所以有些腻了,不过我还是喜欢她的身高和美貌,我想复制出一个身高,体重,胸围和她一样的女孩子,只不过我希望复制出的女孩子非常温柔,善解人意,因为我手里有原型工具,所以我直接开始了,我按照自己的要求输入,然后等待复制,不一会儿,我想要的女孩子出来了,它们一模一样,但是复制出来的女孩子非常温柔。我们具体代码实现一下。


  一.首先定义一个原型类;让其实现Cloneable接口,兵重写Object clone()方法 



  我们充clone()方法中看出它使用了super.clone()进行拷贝,super.clone()是直接使用内存的二进制流进行复制,在复制的时候会为目标对象分配一块内存,所以它们的地址是不相同的,只是类型是相同的。



  由上看出clone()方法由native修饰,可知它调用的不是java层面的方法,而是JVM里面的方法(JVM部分是使用C++进行编写),自然不是基于java层面的构造函数进行复制。

 

  二.客户端调用




  由图可知,我已经复制出一个我喜欢的类型的新女朋友了,她和我原女友在生理上有相同的基因,只不过她很温柔体贴,是我喜爱的类型,到了某一天,我根据她们两个的性格给她们两个安排不同的任务,首先,她们两个都要会做饭,还要会洗衣服,由于原女友脾气火爆,我不让她给我按摩洗脚,我让温柔的新女友给我按摩洗脚,我又一次对她们两个进行改造,我让她们两个开始做任务了。




  但是这下出意外了,大事不好了,我只是让新女友给我按摩洗脚,现在原女友也给我按摩洗脚,他脾气那么火爆,怕是要把我搞死,我仔细想了一下问题出在哪里,苦思冥想许久,原来她们的身高,体重,胸围这些是基本的要求(基本类型),但是她们的任务就不是基本类型了(引用类型),所以在改造过程中出现了问题,导致不该分配的任务分配给了原女友,于是查了很多资料后原来我是对她们进行了浅拷贝,所以才会这样,为了我的生命安危,我需要再次进行改造。

  

  对她们进行深拷贝


  一,对原型类进行一个改造,加上了序列化接口Serializable,它也是一个空接口,我们写了deepClone()方法,使用流和序列化的方式进行复制。



  二,客户端调用。




  发现,原女友没有按摩洗脚的任务了,小命终于保住了,使用了深克隆后,我们发现她们两个的任务不再一样了,为什么之前使用浅克隆是一样的呢,因为她们的任务是一个引用类型,使用浅克隆时复制的其实不是它们的值,而是它们的地址,使用了深克隆后,它们是以流的形式进行复制。

 

  以上是我通过复制女朋友的例子来理解原型模式,只不过现实中我依然还是个单身狗,其实从上面的例子中我们发现只有身高,体重,胸围这三个属性的值没有发生变化,其他的属性我们都重新进行了赋值,那么你可能会说,这没必要使用原型模式吧,是的,少得话可能体现不出来,但是如果这个类的属性特别多,又特别复杂的时候,你还会选择一个一个的取set吗?


目录
相关文章
|
7月前
|
设计模式 安全 Java
面向对象编程的精髓:Java设计模式 - 原型模式(Prototype)完全参考手册
【4月更文挑战第7天】原型模式是OOP中的创建型设计模式,用于通过复制现有实例创建新实例,尤其适用于创建成本高或依赖其他对象的情况。它包括Prototype接口、ConcretePrototype实现和Client客户端角色。优点是性能优化、避免子类化和动态增加产品族。实现包括定义原型接口、实现具体原型和客户端调用克隆方法。最佳实践涉及确保克隆正确性、选择深拷贝或浅拷贝及考虑线程安全。但需注意克隆方法管理、性能开销和循环引用等问题。在Java中,实现Cloneable接口和覆盖clone方法可实现原型模式。
88 4
|
7月前
|
设计模式 Java 关系型数据库
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
|
7月前
|
设计模式 安全 Java
【设计模式】原型模式
【设计模式】原型模式
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
3月前
|
设计模式 Java
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
|
5月前
|
设计模式
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
|
5月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
53 6
|
6月前
|
设计模式 Java
Java设计模式之原型模式详解
Java设计模式之原型模式详解
|
6月前
|
设计模式
原型模式-大话设计模式
原型模式-大话设计模式
|
6月前
|
设计模式 Java Spring
设计模式——原型模式
设计模式——原型模式