所谓的原型模式,就是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
1.首先需要了解java的clone技术
我理解的很简单,无非是把一个对象进行复制粘贴。那么,来看一下JAVA语言中是如何来实现的这个步骤的。我们依次需要知道以下这些事。
1.Object对象中有一个clone()方法。而且是protected。
2.继承于Object的类一般都可以实现这个方法(有特殊的,比如StringBuffer等,官方定的,不去研究它)。
3.想被clone的对象需要实现接口Cloneable。如果此对象的类不能实现接口Cloneable,则会抛出CloneNotSupportedExcetion。
4.所有的数组都被视为实现接口Cloneable。
5.clone分为浅clone(又称影子clone)和深clone。
6.Object类本身不实现接口Cloneable,所以在类为Object的对象上调用clone方法,将会导致在运行时抛出异常。
关键所在深克隆和浅克隆,那到底他们之间有什么区别呢?
首先看一下例子:
public abstract class CloneClass implements Cloneable {
public int aInt;
public Object clone() {
CloneClass o = null;
try {
o = (CloneClass) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
public class UnCloneA {
private int i;
public UnCloneA(int ii) {
i = ii;
}
public void doublevalue() {
i *= 2;
}
public String toString() {
return Integer.toString(i);
}
}
public class CloneB implements Cloneable {
public int aInt;
public UnCloneA unCloneA = new UnCloneA(111);
public Object clone() {
CloneB o = null;
try {
o = (CloneB) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
public class Test {
public static void main(String args[]) {
CloneB b1 = new CloneB();
b1.aInt = 11;
System.out.println("before clone,b1.aInt = " + b1.aInt);
System.out.println("before clone,b1.unCA = " + b1.unCloneA);
CloneB b2 = (CloneB) b1.clone();
b2.aInt = 22;
b2.unCloneA.doublevalue();
System.out.println("=================================");
System.out.println("after clone,b1.aInt = " + b1.aInt);
System.out.println("after clone,b1.unCA = " + b1.unCloneA);
System.out.println("=================================");
System.out.println("after clone,b2.aInt = " + b2.aInt);
System.out.println("after clone,b2.unCA = " + b2.unCloneA);
}
}
输出结果:
before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222
可见,当执行clone这个动作的时候,系统首先开辟一个和它一样的空间。然后分别对其内容进行复制。复制过程中,如果是基本类型,没什么说的,直接把值复制过来。如果不是基本类型,复制的则是该类型对象的引用。
这样的clone就是所谓的浅clone。那很显然,如果上面复制的过程中,对于非基本类型实现的不是一个引用复制,而是创建一个新的一样的对象(其实也是一个clone步骤),那么就是所谓的深clone。对于深度克隆只不过是clone的一种扩展,还有N深clone等等。对于这些,和我们要研究的原型模式没有多少关系。
1、浅克隆:
a. 提供一个类作为克隆的原型,该类实现了Clonable接口
b. 在该类中覆盖Object类的clone()方法,采用super.clone()方法完成克隆
c. 在外部使用场合先产生一个原型对象,然后调用其clone()方法产生克隆对象
2、深克隆:
a. 提供一个类作为克隆的原型,该类实现了Serializable接口
b. 在该类中覆盖Object类的clone()方法,采用序列化的方法完成克隆(对象流的读写)
c.在外部使用场合先产生一个原型对象,然后调用其clone()方法产生克隆对象
二、Prototype模式与深、浅克隆:
使用Object.clone()方法进行的克隆是“浅克隆”-被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。浅克隆的步骤如下:
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()要识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
要实现“深克隆”-被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深克隆需要使用Java中提供的对象串行化功能-即把要复制的对象写入到一个缓冲流,然后通过输入流读入,完成对象的复制
下面是深克隆与浅克隆的代码
public class SuperStar implements Cloneable, Serializable {
public String name;
public int height;
public Skill mySkill;
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
public Object deepClone() throws Exception {
Object o = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); // (ByteArrayOutputStream)此类实现了一个输出流,其中
// 的数据被写入一个字节数组。缓冲区会随着数据的不断写入而自动增长。
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this); // 通过Serialization机制将自身写入该缓冲区
// 找到刚才开辟的缓冲区准备读取
ByteArrayInputStream bis = new ByteArrayInputStream(bos
.toByteArray()); //
ObjectInputStream ois = new ObjectInputStream(bis);
// 将刚才写入的内容读入一个新的对象
o = ois.readObject();
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
public class Skill implements Serializable{
public int strength;
public int jumping;
}
public class Test {
public static void main(String args[]) throws Exception{
SuperStar s1=new SuperStar();
s1.name="姚明";
s1.height=226;
s1.mySkill=new Skill();
s1.mySkill.jumping=50;
s1.mySkill.strength=20;
System.out.println(s1.name+" " + s1.height +" "+s1.mySkill.jumping);
SuperStar s2=(SuperStar) s1.clone();
// SuperStar s2=(SuperStar) s1.deepClone();
s2.name="潘长江";
s2.height=100;
s2.mySkill.jumping=10;
s2.mySkill.strength=5;
System.out.println(s2.name+" " + s2.height+" " +s2.mySkill.jumping);
System.out.println(s1.name+" " + s1.height +" "+s1.mySkill.jumping);
}
}
浅克隆 结果
姚明 226 50
潘长江 100 10
姚明 226 10
深克隆 结果
姚明 226 50
潘长江 100 10
姚明 226 50
JAVA中的clone方法,其实现是native的。这也就意味着它的执行效率是远高于new一个新对象的。所以,当需要生成大量相似对象的时候,可以考虑下应用clone,也就是原形模式。
分享到:
相关推荐
"原型"(Prototype)设计模式是其中的一种,它的主要目标是通过复制现有的对象来创建新的对象,而不是通过构造函数来创建新实例。这种方法尤其适用于当创建新对象的过程复杂或者昂贵时,例如,当对象需要大量初始化...
**原型设计模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数来实例化新对象。在面向对象编程中,当我们需要频繁地创建具有相同或相似属性的对象时,...
Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。...
**原型模式(Prototype模式)**是软件设计模式中的一个经典模式,属于创建型模式。它提供了一种通过复制现有的对象来创建新对象的方式,而无需知道具体创建过程的细节。这种模式在需要频繁创建相似对象时非常有用,...
原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过类构造器。这种模式常用于需要频繁创建相似对象的场景,能够提高性能并减少内存使用。 原型模式的组成 原型接口...
原型模式是设计模式中的一种,它是Java 23种经典设计模式之一,主要用来提高对象创建的效率。在原型模式中,我们通过复制或克隆一个已经存在的对象来创建新的对象,而不是通过构造函数来创建。这种方法尤其适用于当...
在给定的文件"设计模式之Prototype(圆形).doc"中,可能详细阐述了如何将Prototype模式应用于创建圆形对象的例子。在这种情况下,可能会有一个Circle类作为具体原型,它实现了Prototype接口,并且提供了克隆圆形对象...
设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) 结构模式: 设计模式之Facade(外观) 设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计模式之Decorator...
本篇文章将深入探讨“原型模式(Prototype)”这一经典的设计模式,它是面向对象设计的一个重要概念,尤其在C++编程中有着广泛的应用。 原型模式是一种创建型设计模式,它的核心思想是通过复制已有对象来创建新对象,...
**原型模式(Prototype Pattern)**是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,而不是通过构造函数。在某些情况下,当创建新对象的成本非常高时(例如,对象需要大量的初始化操作或者从...
本文将深入探讨Android设计模式中的“原型模式”(Prototype Pattern),并结合提供的"prototype"压缩包中的示例代码进行解析。 原型模式是一种创建型设计模式,它的主要思想是通过复制已有对象来创建新对象,而...
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...
本文将深入探讨一种常见的设计模式——原型模式(Prototype Pattern),并结合具体的iOS应用场景进行解析。 原型模式是一种创建型设计模式,它的主要思想是通过复制已有对象来创建新对象,而不是通过构造函数来创建...
设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) 结构模式: 设计模式之Facade(外观) 设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计模式之Decorator...
第二部分是核心部分,通过一步步完善的代码示例,由浅入深地讲解了16个设计模式,包括 singleton模式、Factory模式、Abstract Factory模式、Builder模式、Prototype模式、Adapter模式、Bridge模式、Composite模式、...
原型模式(Prototype Pattern)是其中一种行为设计模式,主要用于对象创建。它通过复制已有对象来创建新对象,而不是通过传统的构造函数来创建。在Java中,原型模式可以有效地提高性能,特别是在创建复杂对象时。 #...
原型模式(Prototype Pattern)是软件设计模式中的一种结构型模式,它的主要目的是通过复制已有对象来创建新对象,从而减少创建新对象的成本。在原型模式中,类的实例化过程被替换为对已有实例的克隆操作,尤其适用...
├─第一章 旭瑶-小滴...│ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》.mp4 │ 6.1-接口之间的桥梁-适配器设计模式你知道多少.mp4 │ 6.4