Java原型模式实现案例
原型模式(Prototype Pattern)用于创建重复的对象,同时保证性能,它通过克隆现有对象来创建新对象,而不是通过new关键字。

基本原型模式实现
// 1. 实现Cloneable接口的原型类
public class Shape implements Cloneable {
private String id;
protected String type;
public Shape(String id, String type) {
this.id = id;
this.type = type;
}
// 实现克隆方法
@Override
public Shape clone() throws CloneNotSupportedException {
return (Shape) super.clone();
}
// getter和setter方法
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getType() { return type; }
// 抽象方法,由子类实现
public void draw() {
System.out.println("Drawing " + type);
}
}
// 2. 具体原型类
class Circle extends Shape {
private int radius;
public Circle(String id, int radius) {
super(id, "Circle");
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing Circle with radius: " + radius);
}
@Override
public Circle clone() throws CloneNotSupportedException {
return (Circle) super.clone();
}
}
class Rectangle extends Shape {
private int width;
private int height;
public Rectangle(String id, int width, int height) {
super(id, "Rectangle");
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing Rectangle " + width + "x" + height);
}
@Override
public Rectangle clone() throws CloneNotSupportedException {
return (Rectangle) super.clone();
}
}
// 3. 使用原型模式
public class PrototypeDemo {
public static void main(String[] args) throws CloneNotSupportedException {
// 创建原始对象
Circle originalCircle = new Circle("1", 10);
originalCircle.draw();
// 克隆对象
Circle clonedCircle = originalCircle.clone();
clonedCircle.setId("2");
clonedCircle.draw();
System.out.println("Original == Cloned? " + (originalCircle == clonedCircle));
System.out.println("Original equals Cloned? " + originalCircle.equals(clonedCircle));
}
}
深拷贝实现
当对象包含引用类型时,需要使用深拷贝:
import java.util.ArrayList;
import java.util.List;
class Employee implements Cloneable {
private String name;
private List<String> skills;
private Address address;
public Employee(String name) {
this.name = name;
this.skills = new ArrayList<>();
this.address = new Address();
}
// 深拷贝实现
@Override
public Employee clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
// 深拷贝引用类型
cloned.skills = new ArrayList<>(this.skills);
cloned.address = this.address.clone();
return cloned;
}
// 内部类
static class Address implements Cloneable {
private String city;
private String street;
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
// getter/setter
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; }
}
// getter/setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<String> getSkills() { return skills; }
public void setSkills(List<String> skills) { this.skills = skills; }
public Address getAddress() { return address; }
}
原型管理器实现
import java.util.HashMap;
import java.util.Map;
class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
try {
return cachedShape.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
// 加载初始数据
public static void loadCache() {
Circle circle = new Circle("1", 10);
shapeMap.put(circle.getId(), circle);
Rectangle rectangle = new Rectangle("2", 5, 8);
shapeMap.put(rectangle.getId(), rectangle);
}
}
// 使用原型管理器
public class PrototypeManagerDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
// 获取克隆对象
Shape clonedCircle = ShapeCache.getShape("1");
clonedCircle.draw();
Shape clonedRectangle = ShapeCache.getShape("2");
clonedRectangle.draw();
}
}
序列化实现深拷贝
import java.io.*;
class SerializedObject implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient int age; // transient字段不会被序列化
public SerializedObject(String name, int age) {
this.name = name;
this.age = age;
}
// 通过序列化实现深拷贝
public SerializedObject deepClone() {
try {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
oos.close();
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (SerializedObject) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// getter/setter
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; }
}
实际应用示例:数据库连接池
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
class DatabaseConnection implements Cloneable {
private String url;
private String username;
private String password;
private Connection connection;
public DatabaseConnection(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
createConnection();
}
private void createConnection() {
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public DatabaseConnection clone() throws CloneNotSupportedException {
// 浅拷贝连接配置,重新创建连接
DatabaseConnection cloned = (DatabaseConnection) super.clone();
cloned.createConnection(); // 创建新的数据库连接
return cloned;
}
public Connection getConnection() {
return connection;
}
public void close() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
关键要点总结
| 特性 | 说明 |
|---|---|
| Cloneable接口 | 标记接口,必须实现才能使用clone() |
| 浅拷贝 | 默认的clone()方法,复制基本类型和引用类型的引用 |
| 深拷贝 | 需要手动实现,复制所有引用类型的实际对象 |
| 序列化拷贝 | 通过序列化/反序列化实现深拷贝,要求所有类实现Serializable |
| 性能优势 | 克隆通常比new更快(避免构造方法),适合创建大对象 |
使用场景
- 创建对象成本高(数据库连接、大型对象)
- 系统需要独立于对象创建过程
- 需要避免使用构造方法(如需要动态配置)
- 对象有多个可预见的变体
原型模式在需要频繁创建相似对象时非常有用,特别是在对象创建成本较高时。