Java原型模式
原型模式通过复制原型对象创建新对象,避免重复初始化。
模式定义
意图:通过复制现有对象创建新对象,无需知道具体类。
Cloneable接口
Java通过Cloneable接口和clone()方法实现原型模式:
Java
public class User implements Cloneable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected User clone() throws CloneNotSupportedException {
return (User) super.clone(); // 浅拷贝
}
}
// 使用
User original = new User("张三", 25);
User cloned = original.clone();
浅拷贝
浅拷贝只复制基本类型和引用,引用对象共享:
Java
public class Department {
private String name;
}
public class Employee implements Cloneable {
private String name;
private Department dept; // 引用类型
@Override
protected Employee clone() throws CloneNotSupportedException {
return (Employee) super.clone(); // dept引用共享!
}
}
Employee e1 = new Employee("张三", new Department("研发部"));
Employee e2 = e1.clone();
// e1和e2的dept指向同一对象
e2.getDept().setName("市场部");
System.out.println(e1.getDept().getName()); // "市场部"!
深拷贝
深拷贝递归复制所有引用对象:
方式1:手动克隆
Java
public class Department implements Cloneable {
private String name;
@Override
protected Department clone() throws CloneNotSupportedException {
return (Department) super.clone();
}
}
public class Employee implements Cloneable {
private String name;
private Department dept;
@Override
protected Employee clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
cloned.dept = dept.clone(); // 深拷贝
return cloned;
}
}
方式2:序列化
Java
public class Employee implements Serializable {
private String name;
private Department dept;
public Employee deepClone() throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Employee) ois.readObject();
}
}
原型管理器
管理多个原型,通过类型获取克隆:
Java
public class PrototypeManager {
private Map<String, Prototype> prototypes = new HashMap<>();
public void register(String key, Prototype prototype) {
prototypes.put(key, prototype);
}
public Prototype getClone(String key) throws CloneNotSupportedException {
Prototype prototype = prototypes.get(key);
return prototype.clone();
}
}
// 使用
PrototypeManager manager = new PrototypeManager();
manager.register("user", new User("模板", 0));
manager.register("order", new Order());
User user = (User) manager.getClone("user");
实际应用示例
Java
// 文档模板
public class Document implements Cloneable {
private String title;
private String content;
private String author;
private Date createDate;
public Document() {
// 模板初始化
this.title = "默认标题";
this.author = "系统";
this.createDate = new Date();
}
@Override
protected Document clone() throws CloneNotSupportedException {
Document cloned = (Document) super.clone();
cloned.createDate = (Date) createDate.clone(); // 深拷贝
return cloned;
}
}
// 从模板创建新文档
Document template = new Document();
Document doc1 = template.clone();
doc1.setTitle("文档1");
doc1.setAuthor("张三");
Document doc2 = template.clone();
doc2.setTitle("文档2");
doc2.setAuthor("李四");
浅拷贝 vs 深拷贝
| 类型 | 基本类型 | 引用类型 | 性能 |
|---|---|---|---|
| 浅拷贝 | 复制值 | 复制引用 | 快 |
| 深拷贝 | 复制值 | 递归复制 | 慢 |
clone()注意点
Java
// Object.clone()特点:
// 1. 只支持Cloneable接口的类
// 2. 默认浅拷贝
// 3. 不会调用构造器
// 4. protected方法,需重写为public
适用场景
- 创建成本高的对象
- 类初始化消耗大量资源
- 需要大量相似对象
- 隐藏创建复杂性
注意事项
Cloneable是标记接口,无方法
clone()需要重写,默认protected
浅拷贝可能导致数据共享问题
序列化深拷贝要求所有类实现Serializable
复制不会调用构造器,可能绕过检查
要点总结
- 原型模式通过复制创建对象,避免重复初始化
- Java通过Cloneable接口和clone()实现
- 浅拷贝只复制引用,深拷贝递归复制
- 深拷贝可手动实现或用序列化
- 适用于创建成本高的场景
📝 发现内容有误?点击此处直接编辑