【设计模式】原型模式(Prototype Pattern)详解

文章目录

    • [1. 引言:为什么不直接 new?](#1. 引言:为什么不直接 new?)
    • [2. 什么是原型模式](#2. 什么是原型模式)
      • [GoF 定义](#GoF 定义)
    • [3. 原型模式的核心思想](#3. 原型模式的核心思想)
    • [4. 原型模式的角色组成](#4. 原型模式的角色组成)
    • [5. Java 中的原型模式基础:Cloneable](#5. Java 中的原型模式基础:Cloneable)
    • [6. 示例场景:文档模板复制](#6. 示例场景:文档模板复制)
    • [7. 客户端使用](#7. 客户端使用)
    • [8. 浅拷贝 vs 深拷贝(重点)](#8. 浅拷贝 vs 深拷贝(重点))
      • [8.1 浅拷贝(Shallow Copy)](#8.1 浅拷贝(Shallow Copy))
      • [8.2 深拷贝(Deep Copy)](#8.2 深拷贝(Deep Copy))
      • [8.3 深拷贝的常见方式](#8.3 深拷贝的常见方式)
    • [9. 原型模式的优点](#9. 原型模式的优点)
    • [10. 原型模式的缺点](#10. 原型模式的缺点)
    • [11. 适用场景](#11. 适用场景)
    • [12. 原型模式在实际项目中的应用](#12. 原型模式在实际项目中的应用)
    • [13. 原型模式的一个重要提醒](#13. 原型模式的一个重要提醒)
    • 参考

1. 引言:为什么不直接 new?

在日常开发中,我们创建对象通常是这样的:

java 复制代码
MyObject obj = new MyObject();

但在某些场景下,创建一个对象并不"简单"

  • 对象初始化过程复杂
  • 需要访问数据库、配置文件或远程服务
  • 创建成本高、耗时长
  • 对象状态相似,仅少量字段不同

如果每次都通过 new 完整构建对象,会带来明显的性能开销

这时,一个问题出现了:

能不能通过"复制"已有对象来创建新对象?

答案就是------原型模式(Prototype Pattern)

原型模式解决的核心问题是:

如何在创建成本高的前提下,高效地生成相似对象。


2. 什么是原型模式

GoF 定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

一句话理解:

通过 clone 一个已有对象,来生成新对象,而不是重新 new。


3. 原型模式的核心思想

原型模式的核心是两个字:

拷贝

与工厂模式"关注如何创建对象"不同,原型模式关注的是:

  • 如何高效地复制对象
  • 如何避免复杂初始化过程

4. 原型模式的角色组成

原型模式通常包含三个角色:

  • 抽象原型类(Prototype):规定了具体原型对象必须实现的的 clone() 方法。
  • 具体原型类(ConcretePrototype):实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类(Client):使用具体原型类中的 clone() 方法来复制新的对象。

结构非常简单:


5. Java 中的原型模式基础:Cloneable

Java 对原型模式提供了语言级支持:

  • Cloneable 接口

Cloneable 接口中并没有声明任何方法。它只是被用来标记可以使用clone方法进行复制的。这样的接口被称为标记接口(marker interface),如下图。

  • Object.clone() 方法

使用方法:

  1. super:调用父类(Object 类)的 clone() 方法
  2. clone():Object 类中定义的本地(native)方法
  3. 整体意思是:"调用 Object 父类的 clone 方法进行浅拷贝"

6. 示例场景:文档模板复制

假设我们有一个文档对象,初始化过程非常复杂:

java 复制代码
public class Document implements Cloneable {

    private String title;
    private String content;

    public Document(String title, String content) {
        // 模拟复杂初始化
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignored) {}
        this.title = title;
        this.content = content;
    }

    @Override
    protected Document clone() {
        try {
            return (Document) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

注意:

  • Cloneable 是标记接口,没有任何方法
  • clone() 方法定义在 Object 类中,是 protected 方法
  • super 永远指向父类,接口不是父类

7. 客户端使用

java 复制代码
public class Client {
    public static void main(String[] args) {
        Document prototype = new Document("模板", "初始内容");

        Document copy1 = prototype.clone();
        Document copy2 = prototype.clone();
    }
}

效果:

  • 原型只初始化一次
  • 后续对象通过复制生成
  • 性能显著提升

8. 浅拷贝 vs 深拷贝(重点)

这是原型模式中最容易出问题的地方


8.1 浅拷贝(Shallow Copy)

只复制对象本身,引用类型字段仍指向同一对象。

java 复制代码
public class Prototype implements Cloneable {
    private List<String> list;

    @Override
    protected Prototype clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }
}

问题:

  • 修改一个对象的 list
  • 所有 clone 出来的对象都会受影响

8.2 深拷贝(Deep Copy)

不仅复制对象本身,还复制其内部引用对象。

java 复制代码
@Override
protected Prototype clone() throws CloneNotSupportedException {
    Prototype copy = (Prototype) super.clone();
    copy.list = new ArrayList<>(this.list);
    return copy;
}

8.3 深拷贝的常见方式

  1. 手动 clone(最安全)
  2. 序列化 / 反序列化
  3. JSON 转换(不推荐用于高性能场景)

9. 原型模式的优点

  1. 提高性能
  2. 避免复杂初始化
  3. 动态创建对象
  4. 简化工厂类结构

10. 原型模式的缺点

  1. clone 实现复杂
  2. 深拷贝容易出错
  3. 破坏封装性
  4. 对象结构复杂时维护成本高

11. 适用场景

适合使用

  • 创建对象成本高
  • 对象差异小
  • 需要大量相似对象
  • 原型实例较稳定

不适合使用

  • 对象结构频繁变化
  • 包含大量不可变/不可复制资源
  • 业务复杂,维护成本高

12. 原型模式在实际项目中的应用

  • Spring 中的 scope="prototype"
  • 游戏开发中的角色/子弹复制
  • 文档、配置模板
  • UI 组件快速生成

当 new 一个对象太慢时,就考虑原型模式。


13. 原型模式的一个重要提醒

原型模式不是为了"少写代码",而是为了"少做重复初始化"。

如果对象创建本身就很轻量,没必要使用原型模式


参考

原型模式 | 菜鸟教程

原型设计模式

原型模式-百度百科

《图解设计模式》

原型 - Java教程 - 廖雪峰的官方网站

相关推荐
数据与后端架构提升之路17 小时前
系统架构设计师(软考高级)设计模式备考指南
设计模式·系统架构
小小小怪兽17 小时前
聊聊上下文工程👷
设计模式·llm
蔺太微1 天前
桥接模式(Bridge Pattern)
设计模式·桥接模式
zhaokuner1 天前
14-有界上下文-DDD领域驱动设计
java·开发语言·设计模式·架构
Geoking.2 天前
【设计模式】抽象工厂模式(Abstract Factory)详解:一次创建“一整套产品”
设计模式·抽象工厂模式
zhaokuner2 天前
12-深层模型与重构-DDD领域驱动设计
java·开发语言·设计模式·架构
不加糖4352 天前
设计模式 -- 适配器 & 策略模式
python·设计模式
__万波__2 天前
二十三种设计模式(十九)--备忘录模式
java·设计模式·备忘录模式