郑开源的克隆奇遇记-原型模式

引言:一个神奇的复制魔法

在软件开发的世界里,有一种神奇的设计模式,它就像拥有复制魔法一样,能够快速创建对象的副本。今天,让我们跟随主人公郑开源,一起探索这个充满魅力的原型模式(Prototype Pattern)


第一章:郑开源的困惑

故事背景

郑开源是一名资深的Java开发工程师,目前在一家大型互联网公司负责电商系统的开发。最近,他遇到了一个棘手的问题:系统需要频繁创建商品对象,而这些商品对象的创建过程非常复杂且耗时。

// 传统的商品创建方式
public class Product {
   
   
            
    private String name;
    private double price;
    private String category;
    private List<String> tags;
    private ProductDetail detail;
    private List<Review> reviews;
  
    public Product(String name, double price, String category) {
   
   
            
        this.name = name;
        this.price = price;
        this.category = category;
        this.tags = new ArrayList<>();
      
        // 复杂的初始化过程
        this.detail = loadProductDetail(name);
        this.reviews = loadReviews(name);
        calculateRating();
        validateProduct();
        // ... 更多复杂操作
    }
  
    private ProductDetail loadProductDetail(String name) {
   
   
            
        // 模拟从数据库加载详情,耗时操作
        try {
   
   
            
            Thread.sleep(100); // 模拟数据库查询延迟
        } catch (InterruptedException e) {
   
   
            
            Thread.currentThread().interrupt();
        }
        return new ProductDetail(name + "的详细信息");
    }
  
    private List<Review> loadReviews(String name) {
   
   
            
        // 模拟加载评论数据,耗时操作
        try {
   
   
            
            Thread.sleep(50);
        } catch (InterruptedException e) {
   
   
            
            Thread.currentThread().interrupt();
        }
        return Arrays.asList(new Review("好评"), new Review("中评"));
    }
  
    private void calculateRating() {
   
   
            
        // 复杂的评分计算
        System.out.println("计算商品评分...");
    }
  
    private void validateProduct() {
   
   
            
        // 商品数据验证
        System.out.println("验证商品数据...");
    }
}

😰 问题出现

在高并发场景下,郑开源发现系统性能急剧下降:

public class ProductService {
   
   
            
    public void createSimilarProducts() {
   
   
            
        long startTime = System.currentTimeMillis();
      
        // 需要创建100个相似的商品
        List<Product> products = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
   
   
            
            Product product = new Product("商品" + i, 99.9, "电子产品");
            products.add(product);
        }
      
        long endTime = System.currentTimeMillis();
        System.out.println("创建100个商品耗时:" + (endTime - startTime) + "ms");
        // 输出:创建100个商品耗时:15000ms 左右
    }
}

“天哪!创建100个商品竟然需要15秒!”郑开源抓着头发,陷入了沉思。


🔍 第二章:发现原型模式的奥秘

💡 灵感来源

就在郑开源苦恼的时候,他的同事李克隆走过来说:“老郑,你知道吗?在生物学中,有些生物可以通过克隆快速繁殖,比如细菌分裂。在编程中,我们也有类似的机制——原型模式!”

“原型模式?”郑开源眼睛一亮。

李克隆解释道:“原型模式的核心思想是:通过复制现有对象来创建新对象,而不是通过new关键字重新构造。这样可以避免复杂的初始化过程。”

🎯 原型模式的定义

原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

🏗️ 实现原型模式

郑开源立即动手改造他的代码:

// 1. 首先实现Cloneable接口
public class Product implements Cloneable {
   
   
            
    private String name;
    private double price;
    private String category;
    private List<String> tags;
    private ProductDetail detail;
    private List<Review> reviews;
  
    // 构造器(只在创建原型时使用)
    public Product(String name, double price, String category) {
   
   
            
        this.name = name;
        this.price = price;
        this.category = category;
        this.tags = new ArrayList<>();
      
        // 复杂的初始化过程
        this.detail = loadProductDetail(name);
        this.reviews = loadReviews(name);
        calculateRating();
        validateProduct();
    }
  
    // 原型模式的核心:clone方法
    @Override
    public Product clone() {
   
   
            
        try {
   
   
            
            Product cloned = (Product) super.clone();
          
            // 深拷贝可变对象
            cloned.tags = new ArrayList<>(this.tags);
            cloned.detail = this.detail.clone();
            cloned.reviews = new ArrayList<>();
            for (Review review : this.reviews) {
   
   
            
                cloned.reviews.add(review.clone());
            }
          
            return cloned;
        } catch (CloneNotSupportedException e) {
   
   
            
            throw new RuntimeException("克隆失败", e);
        }
    }
  
    // 便于修改克隆后的对象
    public void setName(String name) {
   
   
            
        this.name = name;
    }
  
    public void setPrice(double price) {
   
   
            
        this.price = price;
    }
  
    // ... 其他getter/setter方法
  
    @Override
    public String toString() {
   
   
            
        return "Product{name='" + name + "', price=" + price + 
               ", category='" + category + "'}";
    }
}
// 支持类也需要实现Cloneable
public class ProductDetail implements Cloneable {
   
   
            
    private String description;
    private Map<String, String> attributes;
  
    public ProductDetail(String description) {
   
   
            
        this.description = description;
        this.attributes = new HashMap<>();
    }
  
    @Override
    public ProductDetail clone() {
   
   
            
        try {
   
   
            
            ProductDetail cloned = (ProductDetail) super.clone();
            cloned.attributes = new HashMap<>(this.attributes);
            return cloned;
        } catch (CloneNotSupportedException e) {
   
   
            
            throw new RuntimeException("克隆失败", e);
        }
    }
  
    // ... getter/setter方法
}

public class Review implements Cloneable {
   
   
            
    private String content;
    private int rating;
  
    public Review(String content) {
   
   
            
        this.content = content;
        this.rating = 5;
    }
  
    @Override
    public Review clone() {
   
   
            
        try {
   
   
            
            return (Review) super.clone();
        } catch (CloneNotSupportedException e) {
   
   
            
            throw new RuntimeException("克隆失败", e);
        }
    }
  
    // ... getter/setter方法
}

🎉 测试效果

public class PrototypeTest {
   
   
            
    public static void main(String[] args) {
   
   
            
        // 创建原型对象(只需要一次复杂的初始化)
        System.out.println("创建原型对象...");
        Product prototype = new Product("原型商品", 99.9, "电子产品");
      
        // 使用原型模式创建对象
        long startTime = System.currentTimeMillis();
        List<Product> products = new ArrayList<>();
      
        for (int i = 0; i < 100; i++) {
   
   
            
            Product product = prototype.clone();
            product.setName("商品" + i);
            product.setPrice(99.9 + i);
            products.add(product);
        }
      
        long endTime = System
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容