Skip to content

原型

更新: 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);
    }
}

优缺点

优点:

  1. 性能优化:避免重复初始化开销大的对象
  2. 简化对象创建:隐藏创建细节,客户端只需调用克隆方法
  3. 动态增加产品类:运行时通过克隆创建新类
  4. 避免构造约束:绕过构造函数创建对象

缺点:

  1. 深拷贝实现复杂:需递归克隆引用对象
  2. 破坏封装:需要公开对象的内部结构
  3. 循环引用问题:需特殊处理相互引用的对象

应用场景

  1. 当创建对象成本较高时(如数据库查询结果)
  2. 需要避免使用分层次的工厂类来创建分层次的对象
  3. 需要动态加载类或避免构造约束
  4. 系统需要保存对象状态快照以便回滚

深拷贝与浅拷贝

  • 浅拷贝:复制基本类型字段,引用类型字段复制引用(同一对象)
  • 深拷贝:复制基本类型字段,同时递归复制引用对象(新对象)
  • Java 中实现深拷贝的方法:
    1. 递归实现clone()方法
    2. 对象序列化/反序列化
    3. 使用第三方库如 Apache Commons Lang

与其他模式的关系

  • 原型模式可以替代抽象工厂模式,特别是当对象创建成本高时
  • 抽象工厂模式通常使用工厂方法实现,而原型模式使用克隆
  • 组合模式常与原型模式一起使用,通过递归克隆创建复杂结构

贡献者

The avatar of contributor named as LI SIR LI SIR
The avatar of contributor named as wkwbk wkwbk

页面历史