原型模式(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> {
// 复制
T clone();
}
/**
* 具体原型
*/
class ConcretePotrotypeA implements IPrototype<ConcretePotrotypeA> {
private String desc;
@Override
public 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;
}
@Override
public String toString() {
return "ConcretePotrotypeA{" + "desc='" + desc + '\'' + '}';
}
}
Java内置了 Cloneable抽象原型接口,自定义的类只需要实现该接口并重写 Object.clone()方法即可完成本类的复制。

一般使用 clone方法,需要满足几个条件:
代码如下;
public class ConcretePotrotypeB implements Cloneable{
private String desc;
private List<String> userList;
/**
* 浅拷贝
* @return
*/
@Override
protected 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<String> 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<String> userList;
/**
* 浅拷贝
*
* @return
*/
@Override
protected 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<String> 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));
}

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