创建型模式
- 工厂方法模式(Factory Method Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
- 单例模式(Singleton Pattern)
原型模式(Prototype Pattern) 是一种创建型设计模式,其核心思想是通过复制已有的实例来创建新的对象,而不是通过新建对象的方式。这种模式特别适合于需要大量创建相似对象的场景,能够提高系统性能和效率。
原型模式的定义:
原型模式允许一个对象通过 复制 现有对象来创建新的对象,而无需知道如何具体实现这个对象的类。这种模式通过克隆原有对象来产生新对象,避免了直接使用 new 关键字的开销。
关键概念:
- Prototype(原型) :原型接口或者抽象类,它定义了克隆方法,通常有一个 clone()方法,用于复制当前对象。
- ConcretePrototype(具体原型) :实现 Prototype接口的具体类,通常会提供克隆自己的方法。
- Client(客户端) :通过克隆现有对象来创建新对象的角色,客户端不需要知道如何创建对象,它只需要调用原型对象的 clone()方法即可。
适用场景:
- 当对象创建的成本较高时,可以使用原型模式通过复制已有对象来降低成本。
- 当系统中有很多相似的对象,且这些对象在构建时仅有细微的不同,可以使用原型模式来简化创建过程。
- 当对象的创建过程中需要对一些属性做个性化调整,但大体结构是相似的时,可以使用原型模式。
优缺点分析:
优点:
- 性能优越:通过克隆已有对象创建新对象,相比传统的构造函数创建对象,性能更好,尤其是当构建对象的过程非常复杂时。
- 避免重复创建:如果对象创建过程复杂或开销较大,可以避免重复创建,从而提高效率。
- 灵活性高:客户端不需要知道如何创建对象的具体细节,只需关心对象的克隆。
缺点:
- 复杂性:如果对象包含复杂的成员,且某些成员不适合被浅拷贝(如包含引用类型的成员变量),可能需要额外的工作来确保深拷贝的正确实现。
- 内存消耗:如果使用浅拷贝,可能会出现共享资源的问题,影响对象的独立性。
- 维护性差:当类层次结构复杂或原型对象很难管理时,可能会增加系统的复杂度。
代码示例:
1. 使用原型模式:
// Prototype接口,定义克隆方法
public interface Prototype {
    Prototype clone();
}
// 具体的原型类
public class ConcretePrototype implements Prototype {
    private String name;
    private int age;
    public ConcretePrototype(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 通过构造方法初始化属性
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    // 实现clone方法来复制对象
    @Override
    public Prototype clone() {
        return new ConcretePrototype(this.name, this.age);
    }
    @Override
    public String toString() {
        return "ConcretePrototype{" + "name='" + name + "', age=" + age + '}';
    }
}- 
客户端使用原型: public class PrototypeTest { 
 public static void main(String[] args) {
 // 创建原型对象
 ConcretePrototype prototype1 = new ConcretePrototype("Alice", 30);// 通过克隆方法复制原型对象 ConcretePrototype prototype2 = (ConcretePrototype) prototype1.clone(); // 修改 prototype2 的属性 prototype2.setName("Bob"); prototype2.setAge(25); // 输出对象 System.out.println("Original Object: " + prototype1); System.out.println("Cloned Object: " + prototype2); }} 
3. 输出:
Original Object: ConcretePrototype{name='Alice', age=30}
Cloned Object: ConcretePrototype{name='Bob', age=25}在上面的示例中,ConcretePrototype 实现了 Prototype 接口,并重写了 clone() 方法来复制自己。客户端通过调用 clone() 方法,可以轻松地复制对象,而无需了解对象的构建过程。
深拷贝与浅拷贝
在实际应用中,浅拷贝 (shallow copy)和 深拷贝(deep copy)是原型模式中的两个关键概念:
- 
浅拷贝:拷贝对象时,原始对象的字段值(基本类型数据)会被复制,而引用类型的字段(如对象)则会被复制引用,即两个对象共享相同的引用类型字段。 public class ShallowCopyExample implements Cloneable { 
 private int value;
 private List<String> list;public ShallowCopyExample(int value, List<String> list) { this.value = value; this.list = list; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "ShallowCopyExample{" + "value=" + value + ", list=" + list + '}'; }} 
深拷贝:在进行拷贝时,不仅复制原始对象本身,还会复制其引用类型的所有成员,从而创建完全独立的对象。深拷贝需要通过手动复制每个引用对象来实现。
public class DeepCopyExample implements Cloneable {
    private int value;
    private List<String> list;
    public DeepCopyExample(int value, List<String> list) {
        this.value = value;
        this.list = new ArrayList<>(list);  // 手动复制引用类型成员
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        DeepCopyExample cloned = (DeepCopyExample) super.clone();
        cloned.list = new ArrayList<>(this.list);  // 深拷贝引用类型成员
        return cloned;
    }
    @Override
    public String toString() {
        return "DeepCopyExample{" +
                "value=" + value +
                ", list=" + list +
                '}';
    }
}总结
原型模式是一种通过复制现有对象来创建新对象的设计模式,适用于对象创建开销较大、需要频繁创建相似对象的场景。通过实现 clone() 方法,可以轻松地复制对象。它提供了一种通过已有对象进行对象创建的方式,能有效提高系统性能并简化对象创建过程。但在使用时需要特别注意深拷贝和浅拷贝的区别。