当前位置: 首页 > news >正文

【设计模式】【创建型模式(Creational Patterns)】之原型模式(Prototype Pattern)

1. 设计模式原理说明

原型模式(Prototype Pattern) 是一种创建型设计模式,它允许你通过复制现有对象来创建新对象,而无需通过构造函数来创建。这种方式可以提高性能,尤其是在对象初始化需要消耗大量资源或耗时较长的情况下。原型模式的关键在于对象的克隆方法,通过该方法可以创建一个与原对象具有相同属性的新对象。

主要角色
  1. Prototype(抽象原型类):声明了克隆自身的接口。
  2. ConcretePrototype(具体原型类):实现了克隆方法,用于创建新的对象实例。
  3. Client(客户端):使用原型类创建新对象。

2. UML 类图及解释

UML 类图
+----------------+                +---------------------+
|   Prototype    |                | ConcretePrototype   |
|----------------|                |---------------------|
| + clone(): Prototype            | + clone(): Prototype|
+----------------+                +---------------------++----------------+                         |
|   Client       |                         |
|----------------|                         |
| - prototype: Prototype                  |
|                                +---------+
| + createClone(): Prototype               |
| + mainMethod(): void                     |
+----------------+                         |
类图解释
  • Prototype:定义了一个克隆自身的接口。这个接口通常是一个 clone 方法,用于创建一个新的对象实例。
  • ConcretePrototype:实现了 Prototype 接口中定义的 clone 方法,用于创建新的对象实例。具体的克隆逻辑由具体原型类实现。
  • Client:使用原型类创建新对象。客户端持有一个原型对象的引用,并通过调用其 clone 方法来创建新的对象实例。

3. 代码案例及逻辑详解

Java 代码案例
// 抽象原型类
interface Prototype {Prototype clone();
}// 具体原型类
class ConcretePrototype implements Prototype {private String value;public ConcretePrototype(String value) {this.value = value;}@Overridepublic Prototype clone() {// 浅拷贝return new ConcretePrototype(this.value);}@Overridepublic String toString() {return "ConcretePrototype [value=" + value + "]";}
}// 客户端
class Client {private Prototype prototype;public Client(Prototype prototype) {this.prototype = prototype;}public Prototype createClone() {return prototype.clone();}public static void main(String[] args) {ConcretePrototype original = new ConcretePrototype("Original Value");Client client = new Client(original);ConcretePrototype clone1 = (ConcretePrototype) client.createClone();ConcretePrototype clone2 = (ConcretePrototype) client.createClone();System.out.println("Original: " + original);System.out.println("Clone 1: " + clone1);System.out.println("Clone 2: " + clone2);}
}
C++ 代码案例
#include <iostream>
#include <string>// 抽象原型类
class Prototype {
public:virtual Prototype* clone() const = 0;virtual ~Prototype() {}
};// 具体原型类
class ConcretePrototype : public Prototype {
private:std::string value;public:ConcretePrototype(const std::string& value) : value(value) {}Prototype* clone() const override {return new ConcretePrototype(*this);}friend std::ostream& operator<<(std::ostream& os, const ConcretePrototype& p) {return os << "ConcretePrototype [value=" << p.value << "]";}
};// 客户端
class Client {
private:Prototype* prototype;public:Client(Prototype* prototype) : prototype(prototype) {}Prototype* createClone() {return prototype->clone();}~Client() {delete prototype;}
};int main() {ConcretePrototype original("Original Value");Client client(&original);ConcretePrototype* clone1 = dynamic_cast<ConcretePrototype*>(client.createClone());ConcretePrototype* clone2 = dynamic_cast<ConcretePrototype*>(client.createClone());std::cout << "Original: " << original << std::endl;std::cout << "Clone 1: " << *clone1 << std::endl;std::cout << "Clone 2: " << *clone2 << std::endl;delete clone1;delete clone2;return 0;
}
Python 代码案例
import copy# 抽象原型类
class Prototype:def clone(self):pass# 具体原型类
class ConcretePrototype(Prototype):def __init__(self, value):self.value = valuedef clone(self):# 使用深拷贝return copy.deepcopy(self)def __str__(self):return f"ConcretePrototype [value={self.value}]"# 客户端
class Client:def __init__(self, prototype):self.prototype = prototypedef create_clone(self):return self.prototype.clone()if __name__ == "__main__":original = ConcretePrototype("Original Value")client = Client(original)clone1 = client.create_clone()clone2 = client.create_clone()print("Original:", original)print("Clone 1:", clone1)print("Clone 2:", clone2)
Go 代码案例
package mainimport ("fmt"
)// 抽象原型类
type Prototype interface {Clone() Prototype
}// 具体原型类
type ConcretePrototype struct {Value string
}func (p *ConcretePrototype) Clone() Prototype {// 浅拷贝return &ConcretePrototype{Value: p.Value}
}func (p *ConcretePrototype) String() string {return fmt.Sprintf("ConcretePrototype [value=%s]", p.Value)
}// 客户端
type Client struct {prototype Prototype
}func NewClient(prototype Prototype) *Client {return &Client{prototype: prototype}
}func (c *Client) CreateClone() Prototype {return c.prototype.Clone()
}func main() {original := &ConcretePrototype{Value: "Original Value"}client := NewClient(original)clone1 := client.CreateClone().(*ConcretePrototype)clone2 := client.CreateClone().(*ConcretePrototype)fmt.Println("Original:", original)fmt.Println("Clone 1:", clone1)fmt.Println("Clone 2:", clone2)
}

4. 总结

原型模式 是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过构造函数。这种方式可以提高性能,特别是在对象初始化需要消耗大量资源或耗时较长的情况下。原型模式的主要优点包括:

  1. 性能提升:通过复制现有对象来创建新对象,可以避免复杂的初始化过程,提高性能。
  2. 代码简洁:减少了重复的代码,特别是当对象的初始化过程非常复杂时。
  3. 灵活度高:可以通过修改原型对象的属性来创建不同配置的对象实例。

然而,原型模式也有一些缺点,例如:

  1. 深拷贝和浅拷贝的问题:需要仔细处理对象的深拷贝和浅拷贝问题,否则可能会导致意外的行为。
  2. 类必须实现克隆方法:每个需要被克隆的类都必须实现 clone 方法,这可能会增加代码的复杂性。

总的来说,原型模式在需要频繁创建相似对象的场景中非常有用,但在简单对象的创建中可能显得过于复杂。选择是否使用原型模式应根据具体的需求和场景来决定。

相关文章:

【设计模式】【创建型模式(Creational Patterns)】之原型模式(Prototype Pattern)

1. 设计模式原理说明 原型模式&#xff08;Prototype Pattern&#xff09; 是一种创建型设计模式&#xff0c;它允许你通过复制现有对象来创建新对象&#xff0c;而无需通过构造函数来创建。这种方式可以提高性能&#xff0c;尤其是在对象初始化需要消耗大量资源或耗时较长的情…...

黄仁勋:人形机器人在内,仅有三种机器人有望实现大规模生产

11月23日&#xff0c;芯片巨头、AI时代“卖铲人”和最大受益者、全球市值最高【英伟达】创始人兼CEO黄仁勋在香港科技大学被授予工程学荣誉博士学位&#xff1b;并与香港科技大学校董会主席沈向洋展开深刻对话&#xff0c;涉及人工智能&#xff08;AI&#xff09;、计算力、领导…...

【C语言】宏定义详解

C语言中的宏定义&#xff08;#define&#xff09;详细解析 在C语言中&#xff0c;宏定义是一种预处理指令&#xff0c;使用 #define 关键字定义。它由预处理器&#xff08;Preprocessor&#xff09;在编译前处理&#xff0c;用于定义常量、代码片段或函数样式的代码替换。宏是…...

LangChain——多向量检索器

每个文档存储多个向量通常是有益的。在许多用例中&#xff0c;这是有益的。 LangChain 有一个基础 MultiVectorRetriever &#xff0c;这使得查询此类设置变得容易。很多复杂性在于如何为每个文档创建多个向量。本笔记本涵盖了创建这些向量和使用 MultiVectorRetriever 的一些常…...

《岩石学报》

本刊主要报道有关岩石学基础理论的岩石学领域各学科包括岩浆岩石学、变质岩石学、沉积岩石学、岩石大地构造学、岩石同位素年代学和同位素地球化学、岩石成矿学、造岩矿物学等方面的重要基础理论和应用研究成果&#xff0c;同时也刊载综述性文章、问题讨论、学术动态以及书评等…...

数据结构 (12)串的存储实现

一、顺序存储结构 顺序存储结构是用一组连续的存储单元来存储串中的字符序列。这种存储方式类似于线性表的顺序存储结构&#xff0c;但串的存储对象仅限于字符。顺序存储结构又可以分为定长顺序存储和堆分配存储两种方式。 定长顺序存储&#xff1a; 使用静态数组存储&#xff…...

职场发展陷阱

一、只有执行&#xff0c;没有思考 二、只有过程&#xff0c;没有结果 三、只有重复&#xff0c;没有精进 四、不懂向上管理 五、定期汇报 六、不要憋大招 七、多同步信息...

Xcode15(iOS17.4)打包的项目在 iOS12 系统上启动崩溃

0x00 启动崩溃 崩溃日志&#xff0c;只有 2 行&#xff0c;看不出啥来。 0x01 默认配置 由于我开发时&#xff0c;使用的 Xcode 14.1&#xff0c;打包在另外一台电脑 Xcode 15.3 Xcode 14.1 Build Settings -> Asset Catalog Compliter - Options Xcode 15.3 Build S…...

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【二】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

PVE相关名词通俗表述方式———多处细节实验(方便理解)

PVE设置初期&#xff0c;对CIDR、 网关、 LinuxBridge、VLAN等很有困惑的朋友一定很需要一篇能够全面通俗易懂的方式去理解PVE 中Linux网桥的工作方式&#xff0c;就像操作一个英雄&#xff0c;多个技能&#xff0c;还是需要一点点去学习理解的&#xff0c;如果你上来就对着别人…...

Ansible--自动化运维工具

Ansible自动化运维工具介绍 1.Ansible介绍 Ansible是一款自动化运维工具&#xff0c;基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置、批量程序部署、批量运行命令等功能。…...

微信小程序学习指南从入门到精通

&#x1f5fd;微信小程序学习指南从入门到精通&#x1f5fd; &#x1f51d;微信小程序学习指南从入门到精通&#x1f51d;✍前言✍&#x1f4bb;微信小程序学习指南前言&#x1f4bb;一、&#x1f680;文章列表&#x1f680;二、&#x1f52f;教程文章的好处&#x1f52f;1. ✅…...

微服务篇-深入了解使用 RestTemplate 远程调用、Nacos 注册中心基本原理与使用、OpenFeign 的基本使用

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 框架 2.0 服务调用 2.1 RestTemplate 远程调用 3.0 服务注册和发现 3.1 注册中心原理 3.2 Nacos 注册中心 …...

使用 Django 构建支持 Kubernetes API 测试连接的 POST 接口

文章目录 使用 Django 构建支持 Kubernetes API 测试连接的 POST 接口功能需求使用 kubectl 获取 Token命令解析输出示例 完整代码实现Kubernetes API 客户端类功能说明 Django 接口视图关键点解析 路由配置 接口测试请求示例响应结果成功错误 优化建议1. 安全性2. 错误处理3. …...

十二、正则表达式、元字符、替换修饰符、手势和对话框插件

1. 正则表达式 1.1 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…...

计算机毕业设计Python+大模型美食推荐系统 美食可视化 美食数据分析大屏 美食爬虫 美团爬虫 机器学习 大数据毕业设计 Django Vue.js

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

【后端面试总结】MySQL索引

数据库索引不只一种实现方法&#xff0c;但是其中最具代表性&#xff0c;也是我们面试中遇到最多的无疑是B树。 索引为什么选择B树 数据量很大的查找&#xff0c;是不能直接放入内存的&#xff0c;而是需要什么数据就通过磁盘IO去获得。 红黑树&#xff0c;AVL树等二叉查找树…...

[蓝桥杯 2021 省 AB2] 小平方

题目描述 小蓝发现&#xff0c;对于一个正整数 nn 和一个小于 nn 的正整数 vv&#xff0c;将 vv 平方后对 nn 取余可能小于 nn 的一半&#xff0c;也可能大于等于 nn 的一半。 请问&#xff0c;在 11 到 n−1n−1 中, 有多少个数平方后除以 nn 的余数小于 nn 的一半。 例如&…...

Jmeter测试工具的安装和使用,mac版本,jmeter版本5.2.1

Jmeter测试工具的安装和使用JSON格式请求 一、安装1、安装jdk包和设置java环境2、去官网下载Jmeter3、解压后&#xff0c;打开mac终端&#xff0c;进入apache-jmeter的bin文件开启jmeter 二、使用jmeter1、添加线程2、添加HTTP请求3、配置请求的协议、IP地址、端口号、请求方法…...

kmeans 最佳聚类个数 | 轮廓系数(越大越好)

轮廓系数越大&#xff0c;表示簇内实例之间紧凑&#xff0c;簇间距离大&#xff0c;这正是聚类的标准概念。 簇内的样本应该尽可能相似。不同簇之间应该尽可能不相似。 目的&#xff1a;鸢尾花数据进行kmeans聚类&#xff0c;最佳聚类个数是多少&#xff1f; plot(iris[,1:4…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...