创建型-原型模式
2026/1/15大约 3 分钟Java设计模式创建型模式原型模式Java设计模式面向对象架构设计最佳实践代码优化
概述
原型模式(Prototype Pattern)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用场景
- 创建对象成本较大(如初始化需要占用较长时间、占用太多CPU资源或网络资源)
- 系统要保存对象的状态,而对象的状态变化很小
- 需要避免使用分层次的工厂类来创建分层次的对象
角色组成
- Prototype(抽象原型):声明克隆方法的接口
- ConcretePrototype(具体原型):实现克隆方法
- Client(客户端):通过调用原型对象的克隆方法来创建新对象
代码实现
1. 浅拷贝
public class Sheep implements Cloneable {
private String name;
private int age;
private Sheep friend; // 引用类型
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter 省略
@Override
protected Sheep clone() {
try {
return (Sheep) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}public class Client {
public static void main(String[] args) {
Sheep sheep1 = new Sheep("多利", 2);
Sheep friend = new Sheep("小白", 1);
sheep1.setFriend(friend);
Sheep sheep2 = sheep1.clone();
System.out.println(sheep1 == sheep2); // false
System.out.println(sheep1.getFriend() == sheep2.getFriend()); // true(浅拷贝)
}
}# 输出
false
true2. 深拷贝(重写clone)
public class DeepSheep implements Cloneable {
private String name;
private int age;
private DeepSheep friend;
public DeepSheep(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter 省略
@Override
protected DeepSheep clone() {
try {
DeepSheep cloned = (DeepSheep) super.clone();
// 深拷贝引用类型
if (this.friend != null) {
cloned.friend = this.friend.clone();
}
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}3. 深拷贝(序列化)
import java.io.*;
public class SerializableSheep implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private SerializableSheep friend;
public SerializableSheep(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter 省略
public SerializableSheep 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 (SerializableSheep) ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}public class Client {
public static void main(String[] args) {
SerializableSheep sheep1 = new SerializableSheep("多利", 2);
SerializableSheep friend = new SerializableSheep("小白", 1);
sheep1.setFriend(friend);
SerializableSheep sheep2 = sheep1.deepClone();
System.out.println(sheep1 == sheep2); // false
System.out.println(sheep1.getFriend() == sheep2.getFriend()); // false(深拷贝)
}
}# 输出
false
false原型管理器
public class PrototypeManager {
private static Map<String, Prototype> prototypes = new HashMap<>();
public static void register(String key, Prototype prototype) {
prototypes.put(key, prototype);
}
public static Prototype getPrototype(String key) {
Prototype prototype = prototypes.get(key);
if (prototype != null) {
return prototype.clone();
}
return null;
}
}
// 使用
PrototypeManager.register("sheep", new Sheep("模板羊", 1));
Sheep newSheep = (Sheep) PrototypeManager.getPrototype("sheep");类图
浅拷贝 vs 深拷贝
JDK 中的应用
java.lang.Object#clone()java.util.ArrayList#clone()java.util.HashMap#clone()
优缺点
优点:
- 性能优良,直接拷贝内存二进制流
- 逃避构造函数的约束
缺点:
- 必须实现 Cloneable 接口
- 深拷贝实现复杂
- 需要为每个类配备克隆方法
注意事项
- 使用原型模式复制对象不会调用类的构造方法
- Object 类的 clone 方法只会拷贝对象中的基本数据类型
- 对于数组、容器对象、引用对象等需要另行拷贝
- 深拷贝与浅拷贝问题中,会发生深拷贝的有:
- 8种基本类型及其封装类
- String 类型
