创建型-原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制一个已有的对象(即"原型")来创建新对象,而不是通过构造函数或工厂方法。这种方式可以避免重复的初始化过程,尤其在对象创建代价较大时非常有用。


一、基本概念

🎯 目的

通过克隆已有对象来创建新对象,以提高性能和简化对象创建逻辑。

🧩 主要角色

角色 描述
Prototype(原型接口) 定义克隆自身的接口,通常是 clone() 方法
ConcretePrototype(具体原型类) 实现 clone() 方法的具体类
Client(客户端) 使用原型对象来创建新的对象副本

二、Java 中的实现方式

1. 实现 Cloneable 接口并重写 clone()

java 复制代码
public class Product implements Cloneable {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    protected Product clone() {
        try {
            return (Product) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError(); // 不会发生
        }
    }

    // Getter 和 Setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }

    @Override
    public String toString() {
        return "Product{name='" + name + "', price=" + price + "}";
    }
}

2. 测试使用

java 复制代码
public class Client {
    public static void main(String[] args) {
        Product product1 = new Product("Laptop", 999.99);
        Product product2 = product1.clone();

        System.out.println("Original: " + product1);
        System.out.println("Cloned: " + product2);

        product1.setName("Updated Laptop");
        product1.setPrice(1099.99);

        System.out.println("\nAfter change original:");
        System.out.println("Original: " + product1);
        System.out.println("Cloned: " + product2);
    }
}

三、浅拷贝 vs 深拷贝

类型 是否复制引用字段 实现方式 应用场景
浅拷贝(Shallow Copy) 否(只复制引用地址) 默认 super.clone() 对象不含引用字段或无需隔离引用
深拷贝(Deep Copy) 是(递归复制引用对象) 手动对每个引用字段调用 clone() 或序列化 对象含有嵌套对象,需要完全独立

✅ 示例:深拷贝实现

java 复制代码
class Category implements Cloneable {
    private String categoryName;

    public Category(String categoryName) {
        this.categoryName = categoryName;
    }

    @Override
    protected Category clone() {
        try {
            return (Category) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

    public String getCategoryName() { return categoryName; }
    public void setCategoryName(String categoryName) { this.categoryName = categoryName; }

    @Override
    public String toString() {
        return "Category{" + "categoryName='" + categoryName + "'}";
    }
}

class Product implements Cloneable {
    private String name;
    private double price;
    private Category category;

    public Product(String name, double price, Category category) {
        this.name = name;
        this.price = price;
        this.category = category;
    }

    @Override
    protected Product clone() {
        try {
            Product product = (Product) super.clone();
            if (this.category != null) {
                product.category = this.category.clone(); // 手动深拷贝
            }
            return product;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

    // Getter 和 Setter...
}

四、优点

  • 性能优化:避免复杂的构造逻辑,尤其是创建对象代价较高时。
  • 简化对象创建 :不需要知道对象是如何构建的,只需调用 clone()
  • 动态配置:可以在运行时根据已有对象生成新对象,并进行微调。

五、适用场景

  • 创建对象的代价很大(如频繁访问数据库、远程资源加载等)。
  • 对象之间状态差异小,适合基于已有对象进行微调。
  • 需要动态配置对象结构而不破坏封装性。

六、注意事项

  • 必须实现 Cloneable 接口,否则会抛出异常。
  • 注意区分浅拷贝与深拷贝,避免因引用共享导致的数据污染。
  • 如果类中有 final 字段,可能需要特殊处理(因为不能在克隆后重新赋值)。

如果你有具体的业务需求或想看更复杂的原型模式示例(比如结合 JSON 序列化实现深拷贝),我可以为你提供完整代码示例。

相关推荐
杨充16 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充17 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充17 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充17 小时前
2.面向对象的特性
设计模式
杨充17 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充17 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充17 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯20 小时前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式