学习参考:
http://www.cnblogs.com/hegezhou_hot/archive/2010/12/04/1896471.html
定义:是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
重点:
1、原型模式主要用于对象的复制,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节。
2、使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显
应用场景:原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
类图:
JDK中的体现:
Object.clone;Cloneable
class Prototype implements Cloneable {
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}
class ConcretePrototype extends Prototype{
public void show(){
System.out.println("原型模式实现类");
}
}
public class Client {
public static void main(String[] args){
ConcretePrototype cp = new ConcretePrototype();
ConcretePrototype clonecp = (ConcretePrototype)cp.clone();
clonecp.show();
}
}
输出:
原型模式实现类
扩展:
1、clone方法构造的对象是没有调用构造方法的
class Prototype implements Cloneable {
public Prototype clone() {
Prototype prototype = null;
try {
prototype = (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
class ConcretePrototype extends Prototype {
private static int i = 0;
public ConcretePrototype() {
i++;
}
public void show() {
System.out.println("原型模式实现类" + i);
}
}
public class Test {
public static void main(String[] args) {
ConcretePrototype cp = new ConcretePrototype();
ConcretePrototype clonecp = (ConcretePrototype) cp.clone();
System.out.println(cp == clonecp);
System.out.println(cp.equals(clonecp));
cp.show();
clonecp.show();
}
}
输出:
false
false
原型模式实现类1
原型模式实现类1
如果是走了构造方法,clonecp.show();应该输出2
2、引用只会进行浅拷贝 (prototype 和 clone 的引用实例:是同一个对象)
class P implements Cloneable {
public P clone() {
P prototype = null;
try {
prototype = (P) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
/**
* 引用只会进行浅拷贝,
* @author xinchun.wang
*/
public class A extends P {
private List<String> list = new ArrayList<String>();
private String s = "s";
public static void main(String[] args) {
A a = new A();
A ca = (A)a.clone();
System.out.println(a.equals(ca));//false
System.out.println(a.list == ca.list); //true
a.list.add("aaa");
System.out.println(ca.list); //[aaa]
System.out.println("---------------------------");
System.out.println("a.s: " + a.s);//a.s:s
System.out.println("ca.s: " + ca.s);//ca.s: s
a.s = "b";
System.out.println("a.s: " + a.s);//a.s: b
System.out.println("ca.s: " + ca.s);//ca.s: s
}
}
3、深拷贝与浅拷贝
Object类的clone方法只会拷贝对象中的基本的数据类型(8种基本数据类型byte,char,short,int,long,float,double,boolean),对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的引用对象(数组、容器对象)另行拷贝。
举例:
public class Prototype implements Cloneable {
private ArrayList list = new ArrayList();
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
prototype.list = (ArrayList) this.list.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}
注意:由于ArrayList不是基本类型,所以成员变量list,不会被拷贝,需要我们自己实现深拷贝,幸运的是java提供的大部分的容器类都实现了Cloneable接口。所以实现深拷贝并不是特别困难。
以下是 ArrayList的clone实现,其他引用实现可以参考:
public Object clone() {
try {
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
4、深拷贝的实现举例:
class P implements Cloneable {
}
/**
* @author xinchun.wang
*/
public class A extends P {
@SuppressWarnings("unchecked")
public A clone() {
A prototype = null;
try {
prototype = (A) super.clone();
prototype.list = (List<String>) ((ArrayList<String>)(this.list)).clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
private List<String> list = new ArrayList<String>();
public static void main(String[] args) {
A a = new A();
A ca = a.clone();
a.list.add("aaaa");
System.out.println(a.list); //[aaaa]
System.out.println(ca.list);//[]
}
}
还有一种方式:
序列化实现,把对象写道流里的过程是串行化(Serilization)过程;把对象从流中读出来是并行化(Deserialization)过程. 写在流里的是对象的一个拷贝,然后再从流里读出来重建对象.
public class PrototypeSe implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class NewPrototypeSe implements Serializable {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private PrototypeSe prototype;
public PrototypeSe getPrototype() {
return prototype;
}
public void setPrototype(PrototypeSe prototype) {
this.prototype = prototype;
}
public Object deepClone(){
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
public class TestDeepClone {
public static void main(String[] args) {
// TODO Auto-generated method stub
PrototypeSe po = new PrototypeSe();
po.setName("test1");
NewPrototypeSe se = new NewPrototypeSe();
se.setPrototype(po);
NewPrototypeSe deepClone = (NewPrototypeSe)se.deepClone();
deepClone.getPrototype().setName("test2");
System.out.println("original name:" + se.getPrototype().getName());
System.out.println("cloned name:" + deepClone.getPrototype().getName());
}
}
结果:
original name:test1
cloned name:test2
- 大小: 13.1 KB
- 大小: 38.9 KB
分享到:
相关推荐
├─第一章 旭瑶-小滴...│ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》.mp4 │ 6.1-接口之间的桥梁-适配器设计模式你知道多少.mp4 │ 6.4
C#设计模式(9)-Prototype Pattern C#设计模式(8)-Builder Pattern C#设计模式(7)-Singleton Pattern C#设计模式(6)-Abstract Factory Pattern C#设计模式(5)-Factory Method Pattern C#设计模式(4)...
设计模式之Prototype
1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...
23种设计模式之Prototype模式代码,这是自己学习Prototype模式顺带写的代码,仅供学习交流
JAVA设计模式-day2,请的行业大能讲得课程,涉及:创建模式(5种: 1、 工厂方法模式(Factory Method); 2、 抽象工厂模式; 3、 单例模式(Singleton) • 4、 建造者模式(Builder); 5、 原型模式(Prototype...
Prototype模式 即原型模式,提供一个已经存在的对象进行新对象创建的接口,一般情况下都是使用Clone接口。 此模式非常简单,简单的说就是复制多个当前对象供使用。Prototype模式允许一个对象再创建另外一个可定制...
设计模式精解-GoF 23 种设计模式解析附 C++实现源码 目 录 引 言 0.1 设计模式解析(总序) 0.2 设计模式解析后记 0.3 与作者联系 1 创建型模式 1.1 Factory模式 1.2 AbstactFactory模式 1.3 Singleton...
至于第14章则很快地浏览尚未介绍的设计模式,包括Bridge、Builder、Chain of Responsibility、Flyweight、Interpreter、Mediator、Memento、Prototype,Visitor。第1章还介绍了四个○○基本概念(抽象、封装、继承、...
NULL 博文链接:https://wy649898543.iteye.com/blog/1431591
ProtoType.rarProtoType.rarProtoType.rar原型设计模式
IOS设计模式浅析之原型模式(Prototype)--copy - iOS知识库1
1.2 Smalltalk MVC中的设计模式 1.3 描述设计模式 1.4 设计模式的编目 1.5 组织编目 1.6 设计模式怎样解决设计问题 1.7 怎样选择设计模式 1.8 怎样使用设计模式 第二章 实例研究:设计一个文档编辑器 2.1 设计问题...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
设计模式精解- GoF 23 种设计模式解析附 C++实现源码 目 录 0 引言 ...........................................................................................................................................
或其他很酷的东西) bower install app-prototype 并作为NodeJS包application-prototype sudo npm install -g application-prototype当前对象应用程序设计模式的构建器; 文件应用程序设计模式的构建器,它需要大量...
NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/1032892
设计模式C++学习之原型模式(Prototype)