原型模式(Prototype Pattern)
原型模式是一种 创建型设计模式 ,通过复制现有的实例来创建新的对象,而不是通过实例化(new
)来创建,从而提高性能。
原理
- 核心思想:提供一个现有对象的模板,通过克隆来创建新的对象。
- 适用场景:当对象的创建成本较高,且需要多个类似的对象时,使用原型模式可以提高效率。
- 参与角色 :
- Prototype(原型接口) :定义克隆方法(通常为
clone()
)。 - ConcretePrototype(具体原型类):实现克隆方法,负责实际对象的复制。
- Client(客户端):通过调用克隆方法创建对象。
- Prototype(原型接口) :定义克隆方法(通常为
优点
- 性能高效:通过克隆对象避免了复杂的对象创建过程。
- 动态性强:可以在运行时动态创建对象,而不需要依赖具体类。
- 灵活性:对于复杂对象可以深拷贝,从而实现完全独立的复制。
缺点
- 实现复杂:需要实现深拷贝时,可能会引入额外的复杂性。
- 资源消耗:对于深拷贝,克隆过程可能涉及大量的递归或额外的代码。
示例代码
1. 定义原型接口
java
// 定义原型接口
public interface Prototype extends Cloneable {
Prototype clone();
}
2. 具体原型类
java
// 具体原型类
public class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
// 实现克隆方法
@Override
public Prototype clone() {
try {
return (Prototype) super.clone(); // 浅拷贝
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Clone not supported", e);
}
}
// Getter 和 Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ConcretePrototype{name='" + name + "'}";
}
}
3. 客户端代码
java
public class PrototypeExample {
public static void main(String[] args) {
// 创建一个原型对象
ConcretePrototype prototype = new ConcretePrototype("Original");
// 克隆对象
ConcretePrototype clone1 = (ConcretePrototype) prototype.clone();
ConcretePrototype clone2 = (ConcretePrototype) prototype.clone();
// 修改克隆对象
clone1.setName("Clone 1");
clone2.setName("Clone 2");
// 打印结果
System.out.println("Original: " + prototype);
System.out.println("Clone 1: " + clone1);
System.out.println("Clone 2: " + clone2);
}
}
输出结果
text
Original: ConcretePrototype{name='Original'}
Clone 1: ConcretePrototype{name='Clone 1'}
Clone 2: ConcretePrototype{name='Clone 2'}
深拷贝和浅拷贝
- 浅拷贝 :
- 复制对象时,只复制基本类型字段。
- 对于引用类型字段,只复制引用地址(共享同一个引用对象)。
java
@Override
public Prototype clone() {
try {
return (Prototype) super.clone(); // 默认浅拷贝
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Clone not supported", e);
}
}
- 深拷贝 :
- 复制对象时,除了基本类型字段,还需要递归复制引用类型字段,确保拷贝对象完全独立。
java
@Override
public Prototype clone() {
try {
ConcretePrototype cloned = (ConcretePrototype) super.clone();
cloned.setReference(new Reference(this.reference.getValue())); // 手动深拷贝
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Clone not supported", e);
}
}
使用场景
- 对象创建开销大 :
- 数据库连接对象、线程池对象。
- 重复对象相似度高 :
- 图形界面中的按钮、表单等 UI 元素。
- 需要动态创建类的实例 :
- 在运行时动态加载并复制类。
UML 类图
+-------------------+
| Prototype |
+-------------------+
| + clone() |
+-------------------+
^
|
+-------------------+
| ConcretePrototype |
+-------------------+
| - name |
| + clone() |
+-------------------+
^
|
+-------------------+
| Client |
+-------------------+
小结
- 原型模式通过克隆对象来避免复杂对象的直接创建过程,提高了代码的灵活性和性能。
- 使用时需特别注意 深拷贝 和 浅拷贝 的实现,尤其是对象中包含引用类型时。