-
意图:
用原型实列指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 -
动机:
-
适用性:
当一个系统应该独立于它的产品产品创建、构成和表示时,要使用Prototype模式;以及
当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
为了避免创建一个与产品类层次平行的工厂类层次时;或者
当一个类的实例只能有几个不同状态组合中的一种时。 -
结构:
-
参与者:
ProtoType:声明一个克隆自生的接口。
ConcretePrototype: 实现一个克隆自身的操作。
Client:让一个原型克隆自生从而创建一个新的对象。 -
协作:
客户端请求一个原型克隆自身。 -
效果:
a. 运行时刻增加和删除产品
b. 改变值以指定新对象
c. 改变结构以指定新对象
d. 减少子类的构造
e. 用类动态配置应用 -
实现:
a. 使用一个原型管理器
b. 实现克隆操作
c. 初始化克隆对象 -
代码示例:
/** 根据Java语言特性用Cloneable接口替换结构图中的ProtoType类(或者说是接口) 但是clone()方法是Object类中定义的一个Native的方法 Serializable接口是为了对类的实例进行序列化 **/ public class ConcretePrototype implements Cloneable, Serializable { private String className; private String classDesc; public ConcretePrototype() { } public ConcretePrototype(String className, String classDesc) { this.className = className; this.classDesc = classDesc; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getClassDesc() { return classDesc; } public void setClassDesc(String classDesc) { this.classDesc = classDesc; } /** 浅拷贝 指原型对象和克隆对象在内从中指向同一个对象 使用Object的clone()的方式克隆对象 **/ // @Override // public Object clone() throws CloneNotSupportedException { // return super.clone(); // } /** 深拷贝 指从原型对象中复制一个对象的副本,在赋值给克隆对象 使用序列化的方式克隆对象 **/ @Override protected ConcretePrototype clone() { ConcretePrototype cloneObject = null; ObjectInputStream ois = null; try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos)) { oos.writeObject(this); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ois = new ObjectInputStream(bais); cloneObject = (ConcretePrototype) ois.readObject(); } catch(IOException | ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } return cloneObject; } @Override public String toString() { return "ConcretePrototype{" + "className='" + className + '\'' + ", classDesc='" + classDesc + '\'' + '}'; } }
-
已知应用:
-
相关模式:
Prototype和Abstract Factory模式在某些方面是相互竞争的。但是它们也可以一起使用。
Abstract Factory可以存储一个被克隆的原型集合,并返回产品对象。
大量使用Composite和Decorator模式的设计通常也可从Prototype模式处获益。