设计模式 创建型 原型模式(Prototype Pattern)与 常见技术框架应用 解析

news2025/1/5 18:16:20

在这里插入图片描述

原型模式(Prototype Pattern)是一种创建型设计模式,其核心思想在于通过复制现有的对象(原型)来创建新的对象,而非通过传统的构造函数或类实例化方式。这种方式在需要快速创建大量相似对象时尤为高效,因为它避免了重复的初始化过程。

一、核心思想

原型模式的核心思想是“克隆”生成对象,即基于一个已经存在的对象(原型)来创建新的对象实例。这样做的好处是可以提高对象创建的效率,特别是在对象初始化过程复杂或资源消耗大的情况下。

二、定义与结构

定义

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

结构

原型模式主要包含以下几个角色:

  1. Prototype(抽象原型类):声明一个克隆自己的操作,通常是一个Clone方法。这个接口或抽象类是所有具体原型类的基类。
  2. ConcretePrototype(具体原型类):实现原型接口,提供具体的Clone方法来返回对象的副本。
  3. Client(客户类):创建一个原型对象,并通过调用该对象的克隆方法来创建新的对象实例。
角色

在原型模式中,各个角色分工明确:

  • Prototype:定义了克隆方法的接口,可以是抽象类或接口。
  • ConcretePrototype:实现了Prototype接口,提供了具体的克隆实现。
  • Client:使用原型类来创建新对象的副本。

三、实现步骤及代码示例

以Java为例,展示原型模式的实现步骤和代码示例:

1、定义抽象原型类

public abstract class Prototype implements Cloneable {
    public abstract void show();

    // 克隆方法
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

2、实现具体原型类

public class ConcretePrototype1 extends Prototype {
    private String name;

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

    @Override
    public void show() {
        System.out.println("ConcretePrototype1: " + name);
    }
}

public class ConcretePrototype2 extends Prototype {
    private String description;

    public ConcretePrototype2(String description) {
        this.description = description;
    }

    @Override
    public void show() {
        System.out.println("ConcretePrototype2: " + description);
    }
}

3、客户端代码

public class Client {
    public static void main(String[] args) {
        try {
            Prototype prototype1 = new ConcretePrototype1("Prototype 1");
            Prototype clonedPrototype1 = (Prototype) prototype1.clone();

            prototype1.show();
            clonedPrototype1.show();

            Prototype prototype2 = new ConcretePrototype2("Prototype 2");
            Prototype clonedPrototype2 = (Prototype) prototype2.clone();

            prototype2.show();
            clonedPrototype2.show();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,ConcretePrototype1ConcretePrototype2是具体原型类,它们实现了Prototype接口中的clone方法和show方法。客户端代码通过创建原型对象并调用其clone方法来创建新的对象实例,并展示它们的信息。

四、常见技术框架应用

虽然原型模式在Java等后端语言中更为常见,但在前端技术框架中,如JavaScript(特别是ES6及以后版本),也可以通过对象字面量、Object.create()方法或类(class)来实现类似的功能。

1、使用原生 JavaScript 实现简单原型模式

// 抽象原型(这里简单模拟,以对象形式包含 clone 方法规范)
const prototypeObj = {
    clone: function () {
        let clone = Object.create(this);
        clone.clone = this.clone;
        return clone;
    }
};

// 具体原型:商品卡片原型
const productCardPrototype = Object.create(prototypeObj);
productCardPrototype.image = 'default.jpg';
productCardPrototype.title = 'Default Product';
productCardPrototype.price = 0;

// 创建具体商品卡片实例
const productCard1 = productCardPrototype.clone();
productCard1.image = 'product1.jpg';
productCard1.title = 'Awesome Product 1';
productCard1.price = 19.99;

const productCard2 = productCardPrototype.clone();
productCard2.image = 'product2.jpg';
productCard2.title = 'Fantastic Product 2';
productCard2.price = 29.99;

console.log(productCard1);
console.log(productCard2);

在上述代码中:

  • 首先定义 prototypeObj 作为抽象原型基础,其 clone 方法利用 Object.create 基于当前对象(this)创建新对象,并为新对象也挂载 clone 方法,确保克隆能力延续。
  • productCardPrototype 作为具体原型,继承自抽象原型,初始化一些默认属性。
  • 最后通过多次调用 clone 方法创建不同的商品卡片实例,并按需修改各自属性。

结合 ES6 类实现更规范的原型模式

// 抽象原型(以抽象类形式)
class Prototype {
    constructor() {}
    clone() {
        throw new Error('Abstract clone method must be implemented.');
    }
}

// 具体原型:员工信息原型
class EmployeePrototype extends Prototype {
    constructor(name, age, position) {
        super();
        this.name = name;
        this.age = age;
        this.position = position;
    }
    clone() {
        return new EmployeePrototype(this.name, this.age, this.position);
    }
}

// 客户端使用
const originalEmployee = new EmployeePrototype('John Doe', 30, 'Developer');
const clonedEmployee = originalEmployee.clone();
clonedEmployee.name = 'Jane Smith';

console.log(originalEmployee);
console.log(clonedEmployee);

这里:

  • Prototype 抽象类定义基本结构,clone 方法抛出错误强制子类实现。
  • EmployeePrototype 具体类继承自抽象类,在 clone 方法中通过构造函数创建新的员工对象副本,实现属性复制。
  • 客户端按需求克隆员工对象并修改个别属性。

2、在 React 中的应用

在 React 组件开发中,当需要创建相似的组件实例时,原型模式可间接体现。例如,有一个自定义的 Button 组件:

import React from 'react';

// 基础按钮组件(类似原型)
const BaseButton = ({ text, onClick }) => {
    return <button onClick={onClick}>{text}</button>;
};

// 创建不同样式的按钮实例
const PrimaryButton = (props) => <BaseButton {...props} className="primary-button" />;
const SecondaryButton = (props) => <BaseButton {...props} className="secondary-button" />;

const App = () => {
    const handleClick = () => {
        console.log('Button clicked');
    };
    return (
        <div>
            <PrimaryButton text="Submit" onClick={handleClick} />
            <SecondaryButton text="Cancel" onClick={handleClick} />
        </div>
    );
};

export default App;

这里 BaseButton 可看作原型,PrimaryButtonSecondaryButton 通过复用 BaseButton 的结构,传递不同的 className 属性来生成具有不同样式的按钮实例,类似基于原型的克隆思想,快速构建相似但有差异的组件。

3、在 Vue 中的应用

以 Vue 组件为例,假设有一个模态框(Modal)组件:

<template>
  <div class="modal" v-show="isVisible">
    <div class="modal-content">
      <h3>{{ title }}</h3>
      <p>{{ message }}</p>
      <button @click="closeModal">Close</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Modal',
  data() {
    return {
      isVisible: false,
      title: 'Default Modal',
      message: 'This is a default message.'
    };
  },
  methods: {
    closeModal() {
      this.isVisible = false;
    }
  }
};
</script>

<style scoped>
.modal {
  /* 样式定义 */
}
.modal-content {
  /* 样式定义 */
}
</style>

若要创建多个不同内容的模态框,可在父组件中:

<template>
  <div>
    <Modal ref="modal1" :title="customModal1Title" :message="customModal1Message" />
    <Modal ref="modal2" :title="customModal2Title" :message="customModal2Message" />
    <button @click="openModal1">Open Modal 1</button>
    <button @click="openModal2">Open Modal 2</button>
  </div>
</template>

<script>
import Modal from './Modal.vue';

export default {
  components: { Modal },
  data() {
    return {
      customModal1Title: 'Special Modal 1',
      customModal1Message: 'This is a custom message for modal 1.',
      customModal2Title: 'Unique Modal 2',
      customModal2Message: 'Another custom message for modal 2.'
    };
  },
  methods: {
    openModal1() {
      this.$refs.modal1.isVisible = true;
    },
    openModal2() {
      this.$refs.modal2.isVisible = true;
    }
  }
};
</script>

这里 Modal 组件作为原型,父组件通过传入不同的 titlemessage 属性,类似克隆并定制化模态框实例,满足不同业务场景需求,减少重复代码编写。

五、应用场景

原型模式适用于以下场景:

  1. 避免创建代价高昂的对象:当对象的创建过程非常复杂或昂贵时,可以使用原型模式来避免重复创建。
  2. 减少初始化时间:对于需要频繁创建但内容变化不大的对象,原型模式可以显著减少初始化时间。
  3. 共享技术配置:在应用程序中,如果多个对象共享相同的技术配置,可以使用原型模式来简化配置管理。
  4. 缓存池实现:在需要大量相似对象的情况下,原型模式可以用于缓存池的实现,以提高系统性能。
  5. 游戏开发中的角色复制:在游戏中,经常需要复制游戏中的角色或对象,原型模式非常适合这类需求。
  6. 数据备份和恢复:在数据备份和恢复过程中,原型模式可以用来快速创建数据的副本。
  7. 分布式系统中的对象复制:在分布式系统中,有时需要在不同的节点之间复制对象,原型模式可以帮助实现这一点。
  8. 测试用例生成:在自动化测试中,可以通过原型模式快速生成相似的测试用例,提高测试效率。
  9. 多线程环境下的对象共享:在多线程环境中,有时需要共享某些对象,原型模式可以帮助实现对象的安全共享。
  10. 数据库对象的复制:在数据库操作中,有时需要复制数据库对象,原型模式可以帮助简化这一过程。
  11. 图形用户界面(GUI)组件的复制:在GUI开发中,有时需要复制界面组件,原型模式可以实现这一点。
  12. 配置文件的解析和生成:在处理配置文件时,原型模式可以用来解析和生成配置文件。
  13. 网络请求的模拟:在网络编程中,有时需要模拟网络请求,原型模式可以帮助实现这一点。
  14. 事件处理机制:在事件处理机制中,有时需要复制事件对象,原型模式可以帮助实现这一点。
  15. 资源管理:在资源管理中,有时需要复制资源对象,原型模式可以帮助实现这一点。
  16. 版本控制系统中的文件比较:在版本控制系统中,有时需要比较文件的不同版本,原型模式可以帮助实现这一点。
  17. 文档编辑软件中的样式复制:在文档编辑软件中,有时需要复制样式,原型模式可以帮助实现这一点。
  18. 图像处理软件中的滤镜复制:在图像处理软件中,有时需要复制滤镜,原型模式可以帮助实现这一点。
  19. 音频处理软件中的音效复制:在音频处理软件中,有时需要复制音效,原型模式可以帮助实现这一点。
  20. 视频处理软件中的特效复制:在视频处理软件中,有时需要复制特效,原型模式可以帮助实现这一点。
  21. 虚拟现实(VR)环境中的对象复制:在虚拟现实环境中,有时需要复制虚拟对象,原型模式可以帮助实现这一点。
  22. 增强现实(AR)环境中的对象复制:在增强现实环境中,有时需要复制增强对象,原型模式可以帮助实现这一点。
  23. 机器学习模型的复制:在机器学习中,有时需要复制模型,原型模式可以帮助实现这一点。
  24. 深度学习网络的复制:在深度学习中,有时需要复制神经网络,原型模式可以帮助实现这一点。
  25. 自然语言处理(NLP)任务中的文本处理:在自然语言处理任务中,有时需要复制文本对象,原型模式可以帮助实现这一点。
  26. 计算机视觉任务中的图像处理:在计算机视觉任务中,有时需要复制图像对象,原型模式可以帮助实现这一点。
  27. 语音识别任务中的音频处理:在语音识别任务中,有时需要复制音频对象,原型模式可以帮助实现这一点。
  28. 推荐系统中的用户行为分析:在推荐系统中,有时需要分析用户的行为数据,原型模式可以帮助实现这一点。
  29. 电子商务平台中的商品信息复制:在电子商务平台中,有时需要复制商品信息,原型模式可以帮助实现这一点。
  30. 社交媒体平台上的内容分享:在社交媒体平台上,有时需要分享内容,原型模式可以帮助实现这一点。

六、优缺点

优点

  1. 性能提高:通过复制现有对象来创建新对象,避免了重复的初始化过程,提高了性能。
  2. 灵活性:可以动态地添加和删除原型对象,客户端可以直接使用新增的原型来实例化对象。
  3. 简化代码:避免了重复的代码编写,提高了代码的可维护性和可读性。

缺点

  1. 浅拷贝问题:如果原型对象包含引用类型的成员变量,那么这些成员变量所引用的对象将在原型对象和新对象之间共享,可能会导致意外的副作用。需要特别注意实现深拷贝。
  2. 复杂性增加:实现深拷贝可能会增加代码的复杂性。
  3. 可维护性挑战:如果类的结构中含有许多内部状态,而且这些状态随着时间不断变化,那么维护一个准确的克隆状态可能会非常困难。

综上所述,原型模式是一种高效且灵活的创建型设计模式,适用于需要快速创建大量相似对象的场景。然而,在使用时需要注意浅拷贝和深拷贝的问题,以及可能带来的复杂性和可维护性挑战。

在这里插入图片描述

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

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

相关文章

word无法插入svg格式图片

插入后出现这样的窗口&#xff0c;表明word版本低&#xff0c;没有svg这个选项。 因此这就是区别。在b站找升级word视频。

mysql 报错 ERROR 1396 (HY000) Operation ALTER USER failed for root@localhost 解决方案

参考:https://blog.csdn.net/m0_74824534/article/details/144177078 mysql 修改密码 ALTER USER ‘root’‘localhost’ IDENTIFIED BY ‘123’; 时&#xff0c;报错 ERROR 1396 (HY000): Operation ALTER USER failed for rootlocalhost 解决方案&#xff1a; 2024-4-3 段子…

医学图像分割中故障检测方法的比较基准评测:揭示置信度聚合的作用|文献速递-视觉大模型医疗图像应用

Title 题目 Comparative benchmarking of failure detection methods in medical image segmentation: Unveiling the role of confidence aggregation 医学图像分割中故障检测方法的比较基准评测&#xff1a;揭示置信度聚合的作用 01 文献速递介绍 语义分割是医学图像分析…

线程-7-信号量

互斥访问高效从何谈起&#xff08;上节补充&#xff09; 效率要考虑整体效率 放/取数据时串行&#xff0c;但造数据/处理数据可以并行 多线程时&#xff1a;数据在交易场所中传输确实是互斥&#xff0c;串行的&#xff08;占比时间很短&#xff09; 但生产者获取数据与消费…

行业商机信息付费小程序系统开发方案

行业商机信息付费小程序系统&#xff0c;主要是整合优质行业资源&#xff0c;实时更新的商机信息。在当今信息爆炸的时代&#xff0c;精准、高效地获取行业商机信息对于企业和个人创业者而言至关重要。 一、使用场景 日常浏览&#xff1a;用户在工作间隙或闲暇时间&#xff0c…

Vue 全局事件总线:Vue 2 vs Vue 3 实现

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

活动预告 |【Part2】 Azure 在线技术公开课:迁移和保护 Windows Server 和 SQL Server 工作负载

课程介绍 通过 Microsoft Learn 免费参加 Microsoft Azure 在线技术公开课&#xff0c;掌握创造新机遇所需的技能&#xff0c;加快对 Microsoft 云技术的了解。参加我们举办的“迁移和保护 Windows Server 和 SQL Server 工作负载”活动&#xff0c;了解 Azure 如何为将工作负载…

Docker Compose 构建 EMQX 集群 实现mqqt 和websocket

EMQX 集群化管理mqqt真香 目录 #目录 /usr/emqx 容器构建 vim docker-compose.yml version: 3services:emqx1:image: emqx:5.8.3container_name: emqx1environment:- "EMQX_NODE_NAMEemqxnode1.emqx.io"- "EMQX_CLUSTER__DISCOVERY_STRATEGYstatic"- …

067B-基于R语言平台Biomod2模型的物种分布建模与数据可视化-高阶课程【2025】

课程培训包含&#xff1a;发票全套软件脚本学习数据视频文件导师答疑 本教程旨在通过系统的培训学习&#xff0c;学员可以掌握Biomod2模型最新版本的使用方法&#xff0c;最新版包含12个模型&#xff08;ANN, CTA, FDA, GAM, GBM, GLM, MARS, MAXENT, MAXNET, RF, SRE, XGBOOST…

USB 中断传输的 PID 序列

文章目录 中断传输的 PID 序列全速设备抓包高速设备抓包参考中断传输的 PID 序列 端点在初始化后,从 DATA0 开始,每成功执行一个事务,数据包序列翻转一次(从 DATA0 变为DATA1 或从 DATA1 变为 DATA0)。 数据翻转和传输的个数没有直接关系,只由端点在初始化后处理的总数决…

ESP32物联网无线方案,智能穿戴设备联网通信,产品无线交互应用

在物联网的世界里&#xff0c;每一个设备都不再是孤立的个体&#xff0c;它们通过无线连接芯片相互连接&#xff0c;形成一个庞大的智能网络。这些芯片是实现万物互联的基础&#xff0c;它们使得设备能够相互沟通&#xff0c;共享数据&#xff0c;从而创造出无限的可能性。 这…

C语言格式输出

1.转换字符说明&#xff1a; 2.常用的打印格式&#xff1a; 在 C 语言中&#xff0c;格式输出主要依靠 printf 函数来实现。以下是一些 C 语言格式输出的代码举例及相关说明。 printf("%2d"&#xff0c;123)&#xff0c;因为输出的部分有三位数&#xff0c;但是要求…

GJB系统设计说明模板

GJB系统设计说明模板及详解 1 范围 1.1 标识 1.2 系统概述 1.3 文档概述 2 引用文档 GJB XXX XXX XXX&#xff1b; XXX XXX。 前2章通用不再赘述 3 系统级设计决策 系统设计决策的目的:对系统规格说明中的关键需求(包括功能、质量属性和设计约束)进行分析,得到系统级概念性架构…

windows编译llama.cpp GPU版本

Build 指南 https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md 一、Prerequire 具体步骤&#xff08;以及遇到的坑&#xff09;&#xff1a; 如果你要使用CUDA&#xff0c;请确保已安装。 1.安装 最新的 cmake, git, anaconda&#xff0c; pip 配置pyt…

Unity WebGL 部署IIS

Unity WebGL 部署IIS iis添加网站WebGL配置文件WebGL Gzip模式浏览器加载速度优化iis添加网站 第一步在配置好IIS并且添加网站 WebGL配置文件 在web包Build文件夹同级创建web.config文件 web.config文件内容 <?xml version="1.0" encoding="UTF-8"?…

职场常用Excel基础03-自定义排序

大家好&#xff0c;今天和大家一起分享一下excel中的自定义排序~ 通过排序&#xff0c;用户可以快速地对表格中的数据进行整理&#xff0c;以便更直观地观察趋势、查找特定信息或为后续的数据分析做准备。除了标准的升序和降序排序外&#xff0c;Excel还提供了强大的自定义排序…

每天40分玩转Django:Django类视图

Django类视图 一、知识要点概览表 类别知识点掌握程度要求基础视图View、TemplateView、RedirectView深入理解通用显示视图ListView、DetailView熟练应用通用编辑视图CreateView、UpdateView、DeleteView熟练应用Mixin机制ContextMixin、LoginRequiredMixin理解原理视图配置U…

PgSQL如何用cmd命令行备份和还原数据库

一、备份 备份为压缩的二进制格式&#xff08;通常更快且占用空间更少&#xff09; pg_dump -U username -Fc -h hostname -p port -d dbname -F p -f backup.sql-U username&#xff1a;指定连接数据库的用户名&#xff08;默认是 postgres&#xff09;。-Fc&#xff1a;备…

QT-------------多线程

实现思路 QThread 类简介&#xff1a; QThread 是 Qt 中用于多线程编程的基础类。可以通过继承 QThread 并重写 run() 方法来创建自定义的线程逻辑。新线程的执行从 run() 开始&#xff0c;调用 start() 方法启动线程。 掷骰子的多线程应用程序&#xff1a; 创建一个 DiceThre…

VBA批量插入图片到PPT,一页一图

Sub InsertPicturesIntoSlides()Dim pptApp As ObjectDim pptPres As ObjectDim pptSlide As ObjectDim strFolderPath As StringDim strFileName As StringDim i As Integer 设置图片文件夹路径strFolderPath "C:\您的图片文件夹路径\" 请替换为您的图片文件夹路径…