原型模式
通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。
原型模式要求对象实现一个可以克隆的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。这样,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无需再通过new去创建。
原型模式涉及三种角色:
1.客户角色
客户类提出创建对象的请求
2.抽象原型角色
这是一个抽象原型角色,通常由一个接口或者抽象类实现,此角色给出所有具体原型类所需要的接口。
3.具体原型角色
被复制的角色,此角色需要实现抽象的原型角色所要求的接口。
实例
抽象原型对象
1 public abstract class Prototype implements Cloneable{ 2 3 public Prototype clone(){ 4 Prototype prototype = null; 5 try{ 6 prototype = (Prototype)super.clone(); 7 }catch(Exception e){ 8 e.printStackTrace(); 9 } 10 return prototype; 11 } 12 13 public abstract void show(); 14 }
具体原型对象
1 public class ConcretePrototype extends Prototype{ 2 public void show() { 3 System.out.println("ConcretePrototype show"); 4 } 5 }
客户端调用
1 public static void main(String[] args) { 2 ConcretePrototype cp = new ConcretePrototype(); 3 for(int i = 0;i<10;i++){ 4 ConcretePrototype cloneCp = (ConcretePrototype) cp.clone(); 5 cloneCp.show(); 6 } 7 }
原型模式在java中的应用
原型模式的关注点在于通过克隆自身来获取一个和自身一样的对象,那其实只要是实现了cloneable接口的累都可以算是原型模式的应用,比如arraylist
1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E>, RandomAccess, Cloneable, java.io.Serializable 3 { 4 ... 5 public Object clone() { 6 try { 7 ArrayList<E> v = (ArrayList<E>) super.clone(); 8 v.elementData = Arrays.copyOf(elementData, size); 9 v.modCount = 0; 10 return v; 11 } catch (CloneNotSupportedException e) { 12 // this shouldn't happen, since we are Cloneable 13 throw new InternalError(); 14 } 15 } 16 ... 17 }
原型模式的优点
原型模式创建对象比直接new一个对象在性能上好得多。以为你Object类的clone方法是native方法,直接操作内存中的二进制流,特别是复制大对象时,性能差别很明显。