原型模式(Prototype Pattern)指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,属于创建型设计模式。
原型模式的核心在于复制原型对象。
(1)模式的结构
主要角色如下:
注意:不是通过直接 new关键字而是通过复制对象来实现创建对象的模式被称作原型模式。
优点:
缺点:
代码如下:
public class PrototypePattern {public static void main(String[] args) {ConcretePotrotypeA potrotypeA = new ConcretePotrotypeA();potrotypeA.setDesc("ConcretePotrotypeA");ConcretePotrotypeA clone = potrotypeA.clone();clone.setDesc("clone");System.out.println(potrotypeA);System.out.println(clone);}
}/*** 抽象原型* * @param */
interface IPrototype {// 复制T clone();
}/*** 具体原型*/
class ConcretePotrotypeA implements IPrototype {private String desc;@Overridepublic ConcretePotrotypeA clone() {// 进行复制ConcretePotrotypeA concretePotrotypeA = new ConcretePotrotypeA();concretePotrotypeA.setDesc(this.getDesc());return concretePotrotypeA;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}@Overridepublic String toString() {return "ConcretePotrotypeA{" + "desc='" + desc + '\'' + '}';}
}
Java内置了 Cloneable抽象原型接口,自定义的类只需要实现该接口并重写 Object.clone()方法即可完成本类的复制。

一般使用 clone方法,需要满足几个条件:
代码如下;
public class ConcretePotrotypeB implements Cloneable{private String desc;private List userList;/*** 浅拷贝* @return*/@Overrideprotected ConcretePotrotypeB clone(){ConcretePotrotypeB clone = null;try {/*** super.clone()方法是基于内存二进制流的复制*/clone = (ConcretePotrotypeB) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;}// get/set}
测试:
public static void main(String[] args) {ConcretePotrotypeB potrotypeB = new ConcretePotrotypeB();potrotypeB.setDesc("ConcretePotrotypeB");List userList = new ArrayList<>();userList.add("赵云");userList.add("后裔");potrotypeB.setUserList(userList);ConcretePotrotypeB clone = potrotypeB.clone();clone.setDesc("clone");clone.getUserList().add("安琪拉");System.out.println(potrotypeB);System.out.println(clone);System.out.println(clone == potrotypeB);System.out.println(clone.getClass() == potrotypeB.getClass());System.out.println(clone.equals(potrotypeB));}

注意:
针对引用对象属性的深拷贝, 手动给克隆对象的该属性分配另一块内存即可。在 Java中,如果想要完成原型对象的深克隆,通常使用序列化(Serializable )的方式来完成。
代码如下;
public class ConcretePotrotypeC implements Cloneable, Serializable {private String desc;private List userList;/*** 浅拷贝* * @return*/@Overrideprotected ConcretePotrotypeC clone() {return deepClone();}/*** 深拷贝* * @return*/public ConcretePotrotypeC deepClone() {try {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (ConcretePotrotypeC) ois.readObject();} catch (Exception e) {e.printStackTrace();return null;}}// get/set
}
测试:
public static void main(String[] args) {ConcretePotrotypeC potrotypeC = new ConcretePotrotypeC();potrotypeC.setDesc("ConcretePotrotypeC");List userList = new ArrayList<>();userList.add("赵云");userList.add("后裔");potrotypeC.setUserList(userList);ConcretePotrotypeC clone = potrotypeC.clone();clone.setDesc("clone");clone.getUserList().add("安琪拉");System.out.println(potrotypeC);System.out.println(clone);System.out.println(clone == potrotypeC);System.out.println(clone.getClass() == potrotypeC.getClass());System.out.println(clone.equals(potrotypeC));}

参考文章:
– 求知若饥,虚心若愚。