原型模式
概念
原型模式是一种创建型设计模式,通过复制现有对象来创建新对象,而不是通过构造函数。该模式使用原型实例指定创建对象的种类,并通过复制这些原型实例来生成新对象。
应用场景
- 对象创建成本高:当创建对象的成本较高时,可以通过复制现有对象来节省资源。
- 对象配置复杂:需要频繁创建配置相似但不完全相同的对象时,通过原型模式可以简化配置。
- 需要支持撤销/恢复功能:在某些应用中,需要保存对象的状态,原型模式可以快速复制对象的状态。
- 避免子类化:在不知道要创建多少个具体产品的情况下,使用原型模式可以避免大量的子类化。
注意点
- 深拷贝与浅拷贝:需要明确是使用深拷贝(复制对象及其引用的对象)还是浅拷贝(仅复制对象本身,引用指向同一对象)。
- 克隆失败:如果对象中存在不可克隆的成员,可能会导致克隆失败。
- 序列化:在某些情况下,可以通过序列化和反序列化实现对象的深拷贝。
核心要素
- 原型接口:定义克隆方法。
- 具体原型:实现原型接口并提供具体的克隆实现。
- 客户端:使用原型来创建新对象。
Java代码示例
// 原型接口
interface Prototype {
Prototype clone();
}
// 具体原型
class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public Prototype clone() {
return new ConcretePrototype(name);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype("原型A");
ConcretePrototype clone = (ConcretePrototype) prototype.clone();
System.out.println("克隆对象的名称: " + clone.getName());
}
}
各种变形用法
深拷贝与浅拷贝
通过实现Cloneable
接口来支持深拷贝。class DeepClonePrototype implements Prototype, Cloneable { private List<String> items; public DeepClonePrototype(List<String> items) { this.items = new ArrayList<>(items); } @Override public Prototype clone() { try { DeepClonePrototype clone = (DeepClonePrototype) super.clone(); clone.items = new ArrayList<>(this.items); // 深拷贝 return clone; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
利用序列化实现深拷贝
通过序列化和反序列化实现深拷贝。public class SerializablePrototype implements Prototype, Serializable { private String name; public SerializablePrototype(String name) { this.name = name; } @Override public Prototype clone() { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bis); return (SerializablePrototype) in.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } } }
使用工厂与原型结合
原型模式可以与工厂模式结合使用,以动态创建对象。class PrototypeFactory { private Map<String, Prototype> prototypes = new HashMap<>(); public void registerPrototype(String key, Prototype prototype) { prototypes.put(key, prototype); } public Prototype createPrototype(String key) { Prototype prototype = prototypes.get(key); return prototype != null ? prototype.clone() : null; } }
这些是原型模式的基本知识和变形用法。