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



















暂无评论内容