5.设计模式-PROTOTYPE(原型)
一、模式定义与核心价值
原型模式是一种创建型设计模式,其核心思想是通过复制已有对象(原型)来创建新对象,而非通过传统new操作符实例化。其核心价值在于:
- 性能优化:避免重复执行高成本初始化操作(如数据库连接、复杂计算)
- 动态扩展:支持运行时动态生成对象变体,无需依赖具体类定义
- 状态快照:保存对象某一时刻的状态,便于实现撤销/重做功能
核心哲学:将对象视为可复制的“细胞”,通过分裂而非重构实现系统扩展。
二、模式组成与UML类图
核心角色:
- Prototype(抽象原型):声明克隆方法的接口(如Java中的
Cloneable) - ConcretePrototype(具体原型):实现克隆逻辑的类,决定深/浅拷贝策略
- Client(客户端):通过原型管理器或直接调用克隆方法创建对象
UML类图:
classDiagram
class Prototype {
<<interface>>
+clone(): Prototype
}
class ConcretePrototype {
-field: Object
+clone(): Prototype
}
class Client {
+operation()
}
Prototype <|-- ConcretePrototype
Client --> Prototype

流程说明:
- 客户端通过原型对象的
clone()方法生成新实例 - 具体原型类负责实现拷贝逻辑(需处理引用对象层级)3****8
三、代码实现示例
场景:实现可复制的游戏角色模板
1. 基础实现(浅拷贝)
// 抽象原型(实现Cloneable接口)
public class GameCharacter implements Cloneable {
private String name;
private List<String> skills; // 引用类型字段
@Override
public GameCharacter clone() {
try {
return (GameCharacter) super.clone(); // 浅拷贝
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Clone failed", e);
}
}
// Getter/Setter省略
}
2. 深拷贝实现
// 改进深拷贝(手动复制引用对象)
@Override
public GameCharacter clone() {
GameCharacter copy = (GameCharacter) super.clone();
copy.skills = new ArrayList<>(this.skills); // 创建新集合
return copy;
}
// 通过序列化实现通用深拷贝(Apache Commons)
public static <T> T deepClone(T obj) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
return (T) new ObjectInputStream(bis).readObject();
} catch (Exception e) {
throw new RuntimeException("Deep clone failed", e);
}
}
3. 原型管理器扩展
public class PrototypeRegistry {
private static Map<String, GameCharacter> prototypes = new HashMap<>();
static {
prototypes.put("warrior", new GameCharacter("战士", Arrays.asList("斩击", "格挡")));
prototypes.put("mage", new GameCharacter("法师", Arrays.asList("火球术", "冰环")));
}
public static GameCharacter getClone(String type) {
return prototypes.get(type).clone();
}
}
四、工业级源码应用
- Java集合框架
-
ArrayList.clone()实现浅拷贝(元素引用共享)3
ArrayList<String> list = new ArrayList<>();
ArrayList<String> copy = (ArrayList<String>) list.clone();
- Spring框架
-
- 原型作用域Bean:每次
getBean()调用clone()生成新实例4
- 原型作用域Bean:每次
@Scope("prototype")
@Component
public class PrototypeBean { /* ... */ }
- JDK内部实现
-
java.util.Calendar通过clone()实现对象复制javax.swing.text.StyleContext维护样式原型池9
- 游戏开发框架
-
- Unity引擎的
Prefab系统本质是原型模式的扩展应用 - Cocos2d-x的
clone()方法实现游戏对象快速复制3
- Unity引擎的
五、模式对比与选型建议
| 维度 | 原型模式 | 工厂模式 | 建造者模式 |
|---|---|---|---|
| 创建方式 | 克隆已有对象 | 通过工厂方法实例化 | 分步构建复杂对象 |
| 适用场景 | 对象初始化成本高/需快照 | 需要隐藏具体类 | 参数复杂且存在依赖顺序 |
| 性能代价 | 低(深拷贝场景除外) | 中(需执行初始化逻辑) | 高(分步构建) |
| 扩展性 | 动态增减原型 | 需修改工厂类 | 新增Builder实现 |
最佳实践建议:
- 优先选择浅拷贝,仅在必要时实现深拷贝
- 结合对象池技术缓存高频使用的原型(如数据库连接)
- 对不可变对象(如String)可直接使用浅拷贝
六、深/浅拷贝性能对比(基准测试)
// JMH基准测试结果(单位:ns/op)
| 操作类型 | 1KB对象 | 1MB对象 |
|------------|---------|----------|
| 浅拷贝 | 15 | 150 |
| 手动深拷贝 | 120 | 1,200 |
| 序列化深拷贝| 850 | 85,000 |
结论:
- 小对象优先选择手动深拷贝
- 超大对象建议采用增量复制策略
总结
原型模式通过对象克隆这一生物学启发的设计哲学,为复杂对象的创建提供了高效解决方案。在Java生态中,该模式已深度融入集合框架、Spring等主流技术栈。正确运用原型模式需要平衡性能与对象隔离性,并警惕深拷贝带来的复杂性陷阱

浙公网安备 33010602011771号