My App

原型模式

Prototype — 通过复制已有对象来创建新对象,而不是通过 new

一句话理解

用一个已有对象作为模板,通过克隆(复制)它来创建新对象。

解决什么问题

  • 创建对象的成本很高(比如需要查数据库、做大量计算)
  • 需要创建大量相似对象,只有少数属性不同
  • 想避免复杂的构造逻辑

怎么写

Java 中通过实现 Cloneable 接口:

public class Resume implements Cloneable {
    private String name;
    private String position;
    private String company;

    public Resume(String name) {
        this.name = name;
    }

    public void setPosition(String position) { this.position = position; }
    public void setCompany(String company) { this.company = company; }

    // 克隆方法
    @Override
    public Resume clone() {
        try {
            return (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String toString() {
        return name + " - " + position + " @ " + company;
    }
}
// 使用:基于原型克隆,再修改差异部分
Resume base = new Resume("张三");
base.setPosition("Java 开发");
base.setCompany("公司A");

Resume r2 = base.clone();
r2.setCompany("公司B");  // 只改投递公司

Resume r3 = base.clone();
r3.setCompany("公司C");

System.out.println(base); // 张三 - Java 开发 @ 公司A
System.out.println(r2);   // 张三 - Java 开发 @ 公司B
System.out.println(r3);   // 张三 - Java 开发 @ 公司C

浅拷贝 vs 深拷贝

  • 浅拷贝:只复制基本类型字段,引用类型字段仍然指向同一个对象(super.clone() 默认行为)
  • 深拷贝:引用类型也递归复制,完全独立
// 深拷贝需要手动处理引用类型
@Override
public Resume clone() {
    Resume copy = (Resume) super.clone();
    copy.skills = new ArrayList<>(this.skills);  // 引用类型手动复制
    return copy;
}

前端中的原型模式

JavaScript 的原型链本身就是原型模式的体现:

// Object.create 就是原型模式
const base = { type: 'animal', speak() { console.log('...') } }
const dog = Object.create(base)
dog.speak()  // 通过原型链调用

// 日常中更常用展开运算符做浅拷贝
const config = { ...defaultConfig, timeout: 3000 }

使用场景

  • Object.create()、展开运算符 { ...obj }
  • Java clone() 方法
  • 需要批量创建相似对象的场景
  • Spring 中 @Scope("prototype") 每次获取 Bean 都创建新实例

On this page