【设计模式】原型模式(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教程 - 廖雪峰的官方网站

相关推荐
Engineer邓祥浩4 小时前
设计模式学习(20) 23-18 中介者模式
学习·设计模式·中介者模式
不穿格子的程序员5 小时前
设计模式篇2——观察者模式:以直播间送礼系统举例
java·观察者模式·设计模式
小码过河.5 小时前
设计模式——解释器模式
java·设计模式·解释器模式
懵萌长颈鹿5 小时前
原型模式 (Prototype Pattern)
原型模式
老蒋每日coding6 小时前
AI Agent 设计模式系列(二十)—— 优先级排序设计模式
人工智能·设计模式
鱼跃鹰飞14 小时前
设计模式系列:工厂模式
java·设计模式·系统架构
老蒋每日coding21 小时前
AI Agent 设计模式系列(十九)—— 评估和监控模式
人工智能·设计模式
会员果汁21 小时前
23.设计模式-解释器模式
设计模式·解释器模式
2601_949480061 天前
Flutter for OpenHarmony音乐播放器App实战:定时关闭实现
javascript·flutter·原型模式
「QT(C++)开发工程师」1 天前
C++设计模式
开发语言·c++·设计模式