设计模式——原型设计模式(创建型)

news2025/6/3 10:48:21

摘要

本文详细介绍了原型设计模式,这是一种创建型设计模式,通过复制现有对象(原型)来创建新对象,避免使用new关键字,可提高性能并简化对象创建逻辑。文章阐述了其优点,如提高性能、动态扩展和简化构造逻辑,以及缺点,如深拷贝实现复杂、复杂资源复制困难和易破坏封装性。还介绍了使用条件、结构、实现方式、适合场景和实战示例,并探讨了Spring中原型思想的应用。

1. 原型设计模式定义

原型设计模式是一种创建型设计模式,其核心思想是:通过复制现有的对象(原型)来创建新对象,而不是通过 new 关键字来实例化,从而提高性能并简化对象创建逻辑。使用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。

特性

说明

创建方式

使用已有对象(原型)复制创建,而不是 new

拷贝类型

通常支持 浅拷贝深拷贝

接口

通常实现 Cloneable接口,重写 clone()方法(Java)

性能

适合对象创建代价高、结构复杂的场景

1.1. ✅ 原型模式的优点

  1. 提高性能:避免重复创建复杂对象。
  2. 动态扩展:在运行时动态创建对象。
  3. 简化构造逻辑:不用关心构造细节,只需拷贝。

1.2. ❌ 缺点

  • 深拷贝实现复杂(需注意引用对象)
  • 对象包含复杂资源(如数据库连接)时不易复制
  • 克隆过程容易破坏封装性

1.3. 📌 原型设计模式使用条件

适合以下场景:

场景

说明

对象构造开销大

如数据库连接、网络通信等初始化代价高

对象构造逻辑复杂

包含多个参数、状态配置等

多个相似对象

只需要改变少部分属性

2. 原型设计模式结构

2.1. 原型设计模式类图

  1. 客户(Client)角色:客户类提出创建对象的请求。
  2. 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
  3. 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口

2.2. 原型设计模式时序图

3. 原型设计模式实现方式

原型设计模式的实现方式核心在于 —— 通过克隆现有对象来创建新对象,而不是使用 new。在 Java 中,通常通过实现 Cloneable 接口并重写 clone() 方法来完成。下面是常见的两种实现方式:浅拷贝和深拷贝。

3.1. 🛠️ 原型模式实现方式

实现方式

描述

浅拷贝

复制对象本身,但对象中的引用类型字段只复制地址(共享引用)

深拷贝

复制对象及其引用对象(创建完全独立的新对象)

3.2. ✅ 浅拷贝示例(实现 Cloneable)

@Data
public class Person implements Cloneable {
    private String name;
    private int age;

    @Override
    public Person clone() {
        try {
            return (Person) super.clone(); // 浅拷贝
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

✅ 浅拷贝适用于字段都是基本类型或不可变类型(如 String)。

3.3. ✅ 深拷贝示例(引用字段也复制)

@Data
public class Person implements Cloneable {
    private String name;
    private int age;
    private Address address; // 引用类型

    @Override
    public Person clone() {
        try {
            Person cloned = (Person) super.clone();
            // 深拷贝 Address 对象
            cloned.address = address.clone();
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

@Data
class Address implements Cloneable {
    private String city;

    @Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

3.4. 🔁 使用序列化实现深拷贝(通用方案)

public static <T extends Serializable> T deepCopy(T obj) {
    try (
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos)
    ) {
        oos.writeObject(obj);
        try (
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis)
        ) {
            return (T) ois.readObject();
        }
    } catch (Exception e) {
        throw new RuntimeException("深拷贝失败", e);
    }
}

3.5. 📌 实现步骤总结

步骤

描述

1. 实现 Cloneable接口

否则调用 clone()会抛异常

2. 重写 clone()方法

调用 super.clone()并处理引用类型字段

3. 深拷贝时递归调用子对象的 clone()

保证对象间完全独立

3.6. 💡 Tips(在项目中使用时注意):

  • 不要忘了处理 引用类型字段(深拷贝)
  • 可以用工具类如 Apache Commons Lang 的 SerializationUtils.clone() 简化处理
  • Java record 类型天然不可变,结合原型模式更安全
  • Spring 中 @Scope("prototype") 是原型思想的一种应用

4. 原型设计模式适合场景

原型设计模式(Prototype Pattern)适用于通过复制(克隆)现有对象来快速创建新对象的场景。以下是它适用和不适用的场景对比:

4.1. ✅ 适合使用原型模式的场景

场景

说明

对象创建成本高

构造函数复杂、耗时(如 I/O、数据库、复杂计算)时,通过克隆避免重复创建

对象初始化复杂

需要设置很多配置/参数,克隆一个已初始化好的对象更方便

需要大量相似对象

如游戏中怪物/兵种生成、工作流中节点复制、表单复制等

运行时动态创建对象

不依赖类名和构造函数,只要能访问 prototype 对象即可

避免工厂或 new 创建的耦合

提高系统灵活性,符合开闭原则

4.2. ❌ 不适合使用原型模式的场景

场景

原因

对象结构简单、创建成本低

使用 new即可,没必要增加 clone 成本

对象包含复杂的循环引用关系

clone 实现困难,容易出错

频繁深拷贝,性能反而变差

clone 比 new 还慢,得不偿失

对象包含外部不可复制资源

如线程、Socket、数据库连接等资源不能复制

需要严格控制对象创建流程

比如工厂方法模式更适合定制构造逻辑

4.3. 🧠 实际项目应用建议

建议

说明

复杂对象或批量对象创建场景优先考虑

如任务调度系统中复制任务模板

引用类型多的对象必须小心实现深拷贝

避免共享引用带来的副作用

尽量配合原型注册表(原型缓存池)

管理所有 prototype 模板,集中创建

5. 原型设计模式实战示例

在 Spring 项目中,原型设计模式(Prototype Pattern)最典型的应用方式是使用 Spring 的 @Scope("prototype") 注解来声明一个 Bean 为原型模式,使得每次注入都会创建一个新实例。

5.1. ✅ 示例:批量生成任务模板对象(适合原型模式场景)

5.1.1. 定义一个任务对象(复杂初始化逻辑)

@Data
public class Task implements Cloneable {
    private String name;
    private String type;
    private List<String> steps = new ArrayList<>();

    public Task(String name, String type) {
        this.name = name;
        this.type = type;
        this.steps.add("初始化");
        this.steps.add("执行中");
        this.steps.add("结束");
    }

    @Override
    public Task clone() {
        try {
            Task clone = (Task) super.clone();
            // 深拷贝
            clone.steps = new ArrayList<>(this.steps);
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

5.1.2. Spring容器中定义该对象为原型 Bean

@Configuration
public class TaskConfig {

    @Bean
    @Scope("prototype") // 每次注入时都会创建新实例
    public Task taskPrototype() {
        return new Task("默认任务", "general");
    }
}

5.1.3. 任务服务中使用 Prototype Bean并进行克隆

@Service
public class TaskService {

    @Autowired
    private ApplicationContext applicationContext;

    public Task createNewTask(String name, String type) {
        // 每次从容器获取都会是一个新实例(原型)
        Task prototype = applicationContext.getBean(Task.class);
        Task newTask = prototype.clone(); // 克隆一份再设置参数
        newTask.setName(name);
        newTask.setType(type);
        return newTask;
    }
}

5.1.4. ✅ 为什么这是原型模式适合的场景?

说明

创建成本高

每个任务初始化流程复杂,创建频繁

需要批量创建不同配置的对象

每个任务有不同参数,复用模板快速创建

运行时动态变化

原型对象提供灵活性,可随时根据当前需求构造

6. 原型设计模式思考

6.1. Spring 中 @Scope("prototype") 是原型思想的一种应用?

使用 @Scope("prototype") 标注的 Bean,每次从 Spring 容器中获取时,都会创建一个全新的实例,而不是复用同一个对象。这就是“原型”的核心思想。

Prototype 模式的定义:“用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。”(即:通过复制一个“原型对象”来生成新对象

6.1.1. Spring 中如何实现这个思想?

Prototype 模式要素

Spring 的对应机制

原型对象

Bean 的定义(类 + 配置)

拷贝新对象

每次调用 getBean(),Spring 通过反射“创建新对象”

统一管理原型

由 Spring 容器负责构造、注入依赖等生命周期管理

6.1.2. 示例

@Component
@Scope("prototype")
public class Task {
    public Task() {
        System.out.println("新任务实例被创建");
    }
}
@Autowired
private ApplicationContext applicationContext;

public void createTasks() {
    Task t1 = applicationContext.getBean(Task.class); // 创建一个新实例
    Task t2 = applicationContext.getBean(Task.class); // 再创建一个新实例
    System.out.println(t1 == t2); // false
}

6.1.3. prototype与singleton 的区别

特性

singleton(默认)

prototype

实例个数

全局一个

每次请求新建

生命周期管理

Spring 管

Spring 只负责创建,不管理销毁

适用场景

共享服务、无状态组件

有状态对象、频繁创建的临时对象

博文参考

  • 创建型 - 原型模式(Prototype) | Java 全栈知识体系
  • 原型设计模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过mqtt 点灯

1 解析mqtt 传过来的json 用cjson 解析。 2 类似mvc的结构&#xff0c;调用具体的动作函数 定义设备处理结构体&#xff1a;使用结构体数组映射设备名称与处理函数&#xff0c;实现可扩展的指令分发分离设备逻辑&#xff1a;为每个设备&#xff08;如 LED、Motor&#xff0…

大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大模型篇章已经开始&#xff01; 目前已经更新到了第 22 篇&#xff1a;大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】

项目简介 本系统是一个基于 Spring Boot Vue 技术栈开发的墙绘产品展示交易平台&#xff0c;旨在提供一个高效、便捷的在线商城平台&#xff0c;方便用户浏览、选购墙绘产品&#xff0c;并提供管理员进行商品管理、订单管理等功能。系统采用了前后端分离的架构&#xff0c;前…

【机器学习】支持向量机

文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机&#xff08;SVM&#xff09;是一类按监督学习方式对数据进行二元分类的广义线性分类器&#xff0c;其…

ONLYOFFICE深度解锁系列.4-OnlyOffice客户端原理-真的不支持多端同步

最近很多客户多要求直接部署onlyoffice服务端,还问能否和onlyoffice的客户端进行文件同步,当时真是一脸懵,还有的是老客户,已经安装了onlyoffice协作空间的,也在问如何配置客户端和协作空间的对接。由于问的人太多了,这里统一回复,先说结论,再说原理: 1.onlyoffice document s…

LLMTIME: 不用微调!如何用大模型玩转时间序列预测?

今天是端午节&#xff0c;端午安康&#xff01;值此传统佳节之际&#xff0c;我想和大家分享一篇关于基于大语言模型的时序预测算法——LLMTIME。随着人工智能技术的飞速发展&#xff0c;利用大型预训练语言模型&#xff08;LLM&#xff09;进行时间序列预测成为一个新兴且极具…

2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)

从“0到跑起来一个 Vue 项目”&#xff0c;重点是各个工具之间的关联关系、职责边界和技术演化脉络。 从你写代码 → 到代码能跑起来 → 再到代码可以部署上线&#xff0c;每一步都有不同的工具参与。 &#x1f63a;&#x1f63a;1. 安装 Node.js —— 万事的根基 Node.js 是…

【pycharm】如何连接远程仓库进行版本管理(应用版本)

软件&#xff1a;Pycharm OS&#xff1a;Windows 一、Git基础设置 这里略过Git安装&#xff0c;需要可以参考&#xff1a;windows安装git&#xff08;全网最详细&#xff0c;保姆教程&#xff09;-CSDN博客 1. 配置Git 打开GitBash。分次输入下列命令。 git config --…

linux 1.0.7

用户和权限的含义与作用 linux中的用户和文件 用户的权限是非常重要的 而且有些程序需要使用管理员身份去执行 这些都是非常重要的 不可能让所有的人拥有所有的权限 这样的工具可以避免非法的手段来修改计算机中的数据 linux之所以安全还是权限管理做的很棒 每个登录的用户都有…

IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准

大多数高频仪器&#xff0c;如矢量网络分析仪 &#xff08;VNA&#xff09; 和时域反射仪 &#xff08;TDR&#xff09;&#xff0c;都可以在同轴接口的末端进行非常好的测量。然而&#xff0c;复杂系统中使用的互连很少具有同轴接口。用于表征这些设备的夹具的设计和实施会对测…

Denoising Autoencoders 视频截图 DAEs简单实现 kaggle 去噪编码器

https://www.bilibili.com/video/BV1syzrYaEtw Denoising Autoencoders (DAEs) 是一种无监督学习模型&#xff0c;属于自动编码器&#xff08;Autoencoder&#xff09;的一种扩展形式。它们的目标是通过训练神经网络来学习数据的鲁棒表示&#xff08;robust representation&a…

GoogLeNet网络模型

GoogLeNet网络模型 诞生背景 在2014年的ImageNet图像识别挑战赛中&#xff0c;一个GoogLeNet的网络架构大放异彩&#xff0c;与VGG不同的是&#xff0c;VGG用的是3*3的卷积&#xff0c;而GoogLeNet从1*1到7*7的卷积核都用&#xff0c;也就是使用不同大小的卷积核组合。 网络…

仿真科普|弥合市场需求断层,高性能仿真,“性能”与“安全”如何兼得?

2025年3月&#xff0c;塔塔科技&#xff08;Tata Technologies&#xff09;确认曾在去年遭受勒索软件组织“猎手国际”&#xff08;Hunters International&#xff09;的攻击&#xff0c;1.4TB工程数据被窃取&#xff0c;涉及航空发动机热障涂层工艺参数等超过 73 万份文件。 X…

Maven---配置本地仓库

目录 5. 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5.3 找到配置文件路径&#xff0c;使用VSCode方式打开 5.4 新增一行代码 5.5 复制本地仓库路径&#xff0c;设置存储路径 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5…

【C++ 】智能指针:内存管理的 “自动导航仪”

目录 一、引入 二、智能指针的两大特性&#xff1a; 1、RAII 特点&#xff1a; 好处&#xff1a; 2、行为像指针 三、智能指针起初的缺陷&#xff1a;拷贝问题 四、几种智能指针的介绍。 1、C98出现的智能指针——auto_ptr auto_ptr解决上述拷贝构造的问题&#xff1a…

设备制造行业项目管理难点解析,如何有效解决?

在设备制造行业&#xff0c;项目管理是企业运营的核心环节&#xff0c;直接影响项目交付效率、成本控制和盈利能力。然而&#xff0c;由于行业特性复杂、项目周期长、涉及部门多&#xff0c;企业在实际操作中常常面临诸多管理痛点。金众诚工程项目管理系统&#xff0c;依托金蝶…

浅谈 PAM-2 到 PAM-4 的信令技术演变

通信信令技术演进&#xff1a;从 PAM-2 到 PAM-4 在当今数字化高速发展的时代&#xff0c;数据传输需求呈爆炸式增长&#xff0c;行业对通信带宽的要求愈发严苛。为顺应这一趋势&#xff0c;通信信令技术不断革新&#xff0c;曾经占据主导地位的不归零&#xff08;NRZ&#xff…

Protos-SIP:经典 SIP 协议模糊测试工具!全参数详细教程!Kali Linux教程!

简介 该测试套件的目的是评估会话发起协议 (SIP) 实现的实现级别安全性和稳健性。 Protos-SIP 是一款专为 SIP 协议模糊测试&#xff08;Fuzzing&#xff09;设计的工具&#xff0c;最初由 OUSPG&#xff08;Oulu University Secure Programming Group&#xff09;开发&#…

复数三角不等式简介及 MATLAB 演示

复数三角不等式简介及 MATLAB 演示 1. 复数三角不等式简介 复数三角不等式&#xff08;Complex Triangle Inequality&#xff09;是复数的一种重要性质&#xff0c;它类似于普通的三角不等式&#xff0c;但适用于复数空间。具体来说&#xff0c;复数三角不等式可以描述复数之…

【Doris基础】Apache Doris 基本架构深度解析:从存储到查询的完整技术演进

目录 1 引言 2 Doris 架构全景图 2 核心组件技术解析 2.1 Frontend 层&#xff08;FE&#xff09; 2.2 Backend 层&#xff08;BE&#xff09; 3 数据存储与复制机制 3.1 存储架构演进 3.2 副本复制策略 4 查询处理全流程解析 4.1 查询生命周期 5 高可用设计 5.1 F…