原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需知道具体类的信息。
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serial;
import java.io.Serializable;
// 地址类
@Setter
@Getter
@ToString
public class Address implements Cloneable, Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String street;
private String city;
private String state;
private String zipCode;
public Address() {
}
public Address(String street, String city, String state, String zipCode) {
this.street = street;
this.city = city;
this.state = state;
this.zipCode = zipCode;
}
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serial;
import java.io.Serializable;
// 订单项类
@Setter
@Getter
@ToString
public class OrderItem implements Cloneable, Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String productId;
private String productName;
private int quantity;
private double price;
public OrderItem() {
}
public OrderItem(String productId, String productName, int quantity, double price) {
this.productId = productId;
this.productName = productName;
this.quantity = quantity;
this.price = price;
}
@Override
public OrderItem clone() throws CloneNotSupportedException {
return (OrderItem) super.clone();
}
}
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.*;
// 订单类 - 实现浅克隆
@Setter
@Getter
@ToString
public class Order implements Cloneable {
// getter和setter方法
private String orderId;
private String customerName;
private String customerEmail;
private List<OrderItem> items;
private Address shippingAddress;
private Date orderDate;
private OrderStatus status;
public Order() {
this.items = new ArrayList<>();
}
public Order(String orderId, String customerName, String customerEmail) {
this.orderId = orderId;
this.customerName = customerName;
this.customerEmail = customerEmail;
this.items = new ArrayList<>();
this.orderDate = new Date();
this.status = OrderStatus.PENDING;
}
// 添加订单项
public void addItem(OrderItem item) {
this.items.add(item);
}
// 浅克隆实现
@Override
public Order clone() throws CloneNotSupportedException {
Order clonedOrder = (Order) super.clone();
// 浅克隆:只复制items列表的引用,不复制列表中的元素
clonedOrder.items = new ArrayList<>(this.items);
return clonedOrder;
}
}
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
// 使用Hutool实现深克隆的订单类
@Setter
@Getter
@ToString
public class DeepCloneOrder implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String orderId;
private String customerName;
private String customerEmail;
private List<OrderItem> items;
private Address shippingAddress;
private Date orderDate;
private OrderStatus status;
public DeepCloneOrder() {
this.items = new ArrayList<>();
}
public DeepCloneOrder(String orderId, String customerName, String customerEmail) {
this.orderId = orderId;
this.customerName = customerName;
this.customerEmail = customerEmail;
this.items = new ArrayList<>();
this.orderDate = new Date();
this.status = OrderStatus.PENDING;
}
// 添加订单项
public void addItem(OrderItem item) {
this.items.add(item);
}
}
// 订单状态枚举
public enum OrderStatus {
PENDING, // 待处理
CONFIRMED, // 已确认
SHIPPED, // 已发货
DELIVERED, // 已送达
CANCELLED // 已取消
}
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
// 客户端测试代码
@Slf4j
public class PrototypePatternDemo {
public static void main(String[] args) throws CloneNotSupportedException {
// 创建原始订单
Order originalOrder = new Order("ORD001", "张三", "zhangsan@example.com");
// 添加订单项
originalOrder.addItem(new OrderItem("P001", "iPhone 14", 1, 5999.0));
originalOrder.addItem(new OrderItem("P002", "AirPods Pro", 2, 1999.0));
// 设置收货地址
Address address = new Address("中山路123号", "广州市", "广东省", "510000");
originalOrder.setShippingAddress(address);
log.info("=== 原始订单 ===");
log.info(originalOrder.toString());
// 浅克隆示例
shallowCloneExample(originalOrder);
log.info("========================================");
// 深克隆示例(使用Hutool)
deepCloneExample(originalOrder);
}
// 浅克隆示例
public static void shallowCloneExample(Order originalOrder) throws CloneNotSupportedException {
log.info("=== 浅克隆示例 ===");
// 克隆订单
Order clonedOrder = originalOrder.clone();
// 修改克隆订单的信息(这些是基本类型或新对象,不会影响原始订单)
clonedOrder.setOrderId("ORD002");
clonedOrder.setCustomerName("李四");
clonedOrder.setCustomerEmail("lisi@example.com");
// 修改订单项(演示浅克隆的问题)
if (!clonedOrder.getItems().isEmpty()) {
OrderItem firstItem = clonedOrder.getItems().get(0);
firstItem.setProductName("iPhone 14 Pro"); // 修改克隆订单的第一个商品名
}
log.info("原始订单第一个商品: " + originalOrder.getItems().get(0).getProductName());
log.info("克隆订单第一个商品: " + clonedOrder.getItems().get(0).getProductName());
log.info("注意:由于是浅克隆,修改克隆订单的商品名也影响了原始订单!");
log.info("原始订单: " + originalOrder.getOrderId() + " - " + originalOrder.getCustomerName());
log.info("克隆订单: " + clonedOrder.getOrderId() + " - " + clonedOrder.getCustomerName());
log.info("注意:订单ID和客户名是独立的,修改克隆订单不会影响原始订单的这些属性");
}
// 深克隆示例(使用Hutool)
public static void deepCloneExample(Order originalOrder) {
log.info("=== 深克隆示例(使用Hutool)===");
// 创建用于深克隆的订单对象
DeepCloneOrder deepOriginalOrder = new DeepCloneOrder(
originalOrder.getOrderId(),
originalOrder.getCustomerName(),
originalOrder.getCustomerEmail()
);
// 复制订单项
for (OrderItem item : originalOrder.getItems()) {
deepOriginalOrder.addItem(new OrderItem(
item.getProductId(),
item.getProductName(),
item.getQuantity(),
item.getPrice()
));
}
// 复制地址
Address originalAddress = originalOrder.getShippingAddress();
if (originalAddress != null) {
deepOriginalOrder.setShippingAddress(new Address(
originalAddress.getStreet(),
originalAddress.getCity(),
originalAddress.getState(),
originalAddress.getZipCode()
));
}
// 使用Hutool进行深克隆,前提是对象必须实现Serializable接口。
DeepCloneOrder deepClonedOrder = ObjectUtil.cloneByStream(deepOriginalOrder);
// 修改克隆订单的信息
deepClonedOrder.setOrderId("ORD003");
deepClonedOrder.setCustomerName("王五");
deepClonedOrder.setCustomerEmail("wangwu@example.com");
// 修改订单项(演示深克隆的效果)
if (!deepClonedOrder.getItems().isEmpty()) {
OrderItem firstItem = deepClonedOrder.getItems().get(0);
firstItem.setProductName("iPhone 14 Pro Max"); // 修改克隆订单的第一个商品名
}
log.info("原始订单第一个商品: " + deepOriginalOrder.getItems().get(0).getProductName());
log.info("深克隆订单第一个商品: " + deepClonedOrder.getItems().get(0).getProductName());
log.info("注意:由于是深克隆,修改克隆订单的商品名不会影响原始订单!");
log.info("原始订单: " + deepOriginalOrder.getOrderId() + " - " + deepOriginalOrder.getCustomerName());
log.info("深克隆订单: " + deepClonedOrder.getOrderId() + " - " + deepClonedOrder.getCustomerName());
}
}