`

设计模式-Prototype

阅读更多
学习参考:
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
0
1
分享到:
评论

相关推荐

    小D深入浅出设计模式+框架源码剖析实战

    ├─第一章 旭瑶-小滴...│ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》.mp4 │ 6.1-接口之间的桥梁-适配器设计模式你知道多少.mp4 │ 6.4

    C#设计模式-吕震宇

    C#设计模式(9)-Prototype Pattern C#设计模式(8)-Builder Pattern C#设计模式(7)-Singleton Pattern C#设计模式(6)-Abstract Factory Pattern C#设计模式(5)-Factory Method Pattern C#设计模式(4)...

    java设计模式---诙谐易懂版

    根据给定文件内容,以下是关于Java设计模式的知识点说明: 1. 策略模式(Strategy Pattern)是一种行为设计模式,允许在运行时选择算法的行为。策略模式的意图是定义一系列算法,将每个算法封装起来,并使它们可以...

    JAVA设计模式-chm版

    Java设计模式是软件开发中的一种最佳实践,它总结了在解决特定问题时程序员们经常采用的有效方法。这个“JAVA设计模式-chm版”资源显然包含了关于Java设计模式的详细信息,便于理解和应用。设计模式是对常见问题的...

    设计模式之Prototype(原型)

    "原型"(Prototype)设计模式是其中的一种,它的主要目标是通过复制现有的对象来创建新的对象,而不是通过构造函数来创建新实例。这种方法尤其适用于当创建新对象的过程复杂或者昂贵时,例如,当对象需要大量初始化...

    Java 中的设计模式 - jdon

    《Java中的设计模式 - jdon》是一本深入探讨Java编程中设计模式的电子书,它主要聚焦于如何在实际开发中应用和理解这些经典的设计原则和模式。设计模式是软件工程中的一种最佳实践,它总结了在特定上下文中解决常见...

    设计模式-可复用面向对象软件的基础

    《设计模式-可复用面向对象软件的基础》这本书是面向对象编程领域中的一部经典之作。设计模式,作为软件工程中的重要概念,是解决常见问题的成熟解决方案的模板,它在实践中被反复验证并广泛接受。这本书深入浅出地...

    23种 设计模式---面向对象的基本原则

    设计模式是软件工程中的一种最佳实践,它们是解决常见编程问题的经验总结,为软件开发提供了可复用的解决方案。在面向对象编程中,设计模式基于一些基本原则,这些原则构成了良好设计的基础。本篇将深入探讨23种设计...

    设计模式--java版.rar

    设计模式是软件工程中的一种最佳实践,它是在特定情境下为解决常见问题而形成的一套可复用的解决方案模板。Java作为广泛应用的编程语言,其设计模式的应用对于编写高效、可维护的代码至关重要。本资源“设计模式--...

    jquery简单三层通用CRM-prototype

    "三层"通常指应用程序的架构模式,包括表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。这种架构有助于代码的组织和模块化,提高代码的可维护性和复用性。"CRM-prototype"则说明这是一个客户关系管理系统的...

    原型设计模式prototype

    **原型设计模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数来实例化新对象。在面向对象编程中,当我们需要频繁地创建具有相同或相似属性的对象时,...

    23种设计模式之Prototype模式代码

    **原型模式(Prototype模式)**是软件设计模式中的一个经典模式,属于创建型模式。它提供了一种通过复制现有的对象来创建新对象的方式,而无需知道具体创建过程的细节。这种模式在需要频繁创建相似对象时非常有用,...

    设计模式 -- 模仿女娲造物(入门)

    压缩包中的文件名为“ren”,这可能代表了某种与人类或者角色相关的例子,作者可能用这个例子来演示如何使用设计模式来创建和管理软件对象,如使用原型模式(Prototype)创建对象的克隆,或者使用职责链模式(Chain...

    Python编程 -设计模式-从入门到实践

    在编程领域,设计模式是一种被广泛接受的解决常见问题的最佳实践。它们是经过时间验证的、可重用的解决方案,可以提升代码的可读性、可维护性和复用性。当我们谈论“Python编程 - 设计模式 - 从入门到实践”时,这...

    设计模式精解-GoF 23种设计模式解析附C++.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现 #### 0. 引言 设计模式作为面向对象编程的核心组成部分,是软件开发者在长期实践中总结出来的最佳实践。通过深入理解这些设计模式,我们可以更好地进行面向...

    JAVA设计模式-day2.pdf

    JAVA设计模式-day2,请的行业大能讲得课程,涉及:创建模式(5种: 1、 工厂方法模式(Factory Method); 2、 抽象工厂模式; 3、 单例模式(Singleton) • 4、 建造者模式(Builder); 5、 原型模式(Prototype...

    设计模式-可复用面向对象软件的基础.rar

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决常见问题的最佳实践。这些模式已经被广泛接受,并在面向对象编程中被广泛应用,以提高代码的可读性、可维护性和可复用性。《设计模式-可复用面向对象...

Global site tag (gtag.js) - Google Analytics