原型
更新: 6/22/2025 字数: 0 字 时长: 0 分钟
定义
原型模式 (Prototype Pattern) 通过复制现有实例来创建新对象,而不是通过新建类实例。该模式的核心是原型接口,声明了克隆自身的方法。
角色
- 原型接口 (Prototype): 声明克隆方法的接口
- 具体原型 (ConcretePrototype): 实现克隆方法的具体类
- 客户端 (Client): 通过克隆原型来创建新对象
实现
java
import java.util.HashMap;
import java.util.Map;
// 原型接口
interface Prototype {
Prototype clone();
}
// 具体原型 1:简历
class Resume implements Prototype {
private String name;
private String workExperience;
public Resume(String name) {
this.name = name;
}
public void setWorkExperience(String workExperience) {
this.workExperience = workExperience;
}
@Override
public Prototype clone() {
Resume clone = new Resume(this.name);
clone.setWorkExperience(this.workExperience);
return clone;
}
@Override
public String toString() {
return "Resume{" +
"name='" + name + '\'' +
", workExperience='" + workExperience + '\'' +
'}';
}
}
// 具体原型 2:图形
abstract class Shape implements Prototype {
protected String type;
protected int x;
protected int y;
protected String color;
@Override
public abstract Shape clone();
public void move(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return type + "{" +
"x=" + x +
", y=" + y +
", color='" + color + '\'' +
'}';
}
}
class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
public Circle clone() {
Circle clone = new Circle();
clone.x = this.x;
clone.y = this.y;
clone.color = this.color;
return clone;
}
}
class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
public Rectangle clone() {
Rectangle clone = new Rectangle();
clone.x = this.x;
clone.y = this.y;
clone.color = this.color;
return clone;
}
}
// 原型管理器
class PrototypeManager {
private static Map<String, Prototype> prototypes = new HashMap<>();
static {
prototypes.put("simpleResume", new Resume("张三"));
prototypes.put("redCircle", createRedCircle());
prototypes.put("blueRectangle", createBlueRectangle());
}
private static Circle createRedCircle() {
Circle circle = new Circle();
circle.color = "red";
return circle;
}
private static Rectangle createBlueRectangle() {
Rectangle rect = new Rectangle();
rect.color = "blue";
return rect;
}
public static Prototype getPrototype(String key) {
Prototype prototype = prototypes.get(key);
return prototype != null ? prototype.clone() : null;
}
}
// 客户端
public class PrototypeClient {
public static void main(String[] args) {
// 克隆简历
Resume originalResume = new Resume("李四");
originalResume.setWorkExperience("5 年 Java 开发");
Resume clonedResume = (Resume) originalResume.clone();
clonedResume.setWorkExperience("3 年前端开发");
System.out.println("原始简历:" + originalResume);
System.out.println("克隆简历:" + clonedResume);
// 使用原型管理器
Circle circle = (Circle) PrototypeManager.getPrototype("redCircle");
circle.move(10, 20);
System.out.println("红色圆形:" + circle);
Rectangle rectangle = (Rectangle) PrototypeManager.getPrototype("blueRectangle");
rectangle.move(30, 40);
System.out.println("蓝色矩形:" + rectangle);
// 克隆修改后的圆形
Circle clonedCircle = circle.clone();
clonedCircle.move(50, 60);
System.out.println("克隆圆形:" + clonedCircle);
}
}
优缺点
优点:
- 性能优化:避免重复初始化开销大的对象
- 简化对象创建:隐藏创建细节,客户端只需调用克隆方法
- 动态增加产品类:运行时通过克隆创建新类
- 避免构造约束:绕过构造函数创建对象
缺点:
- 深拷贝实现复杂:需递归克隆引用对象
- 破坏封装:需要公开对象的内部结构
- 循环引用问题:需特殊处理相互引用的对象
应用场景
- 当创建对象成本较高时(如数据库查询结果)
- 需要避免使用分层次的工厂类来创建分层次的对象
- 需要动态加载类或避免构造约束
- 系统需要保存对象状态快照以便回滚
深拷贝与浅拷贝
- 浅拷贝:复制基本类型字段,引用类型字段复制引用(同一对象)
- 深拷贝:复制基本类型字段,同时递归复制引用对象(新对象)
- Java 中实现深拷贝的方法:
- 递归实现
clone()
方法 - 对象序列化/反序列化
- 使用第三方库如 Apache Commons Lang
- 递归实现
与其他模式的关系
- 原型模式可以替代抽象工厂模式,特别是当对象创建成本高时
- 抽象工厂模式通常使用工厂方法实现,而原型模式使用克隆
- 组合模式常与原型模式一起使用,通过递归克隆创建复杂结构