设计模式11-原型模式
设计模式11-原型模式
- 写在前面
- 对象创建模式
- 典型模式
- 原型模式
- 动机
- 结构
- 代码推导
- 应用
- 特点
- 要点总结
- 原型模式与工厂方法模式对比
- 工厂方法模式
- 原型模式
- 什么时候用什么模式
写在前面
对象创建模式
通过对象创建模式绕开动态内存分配来避免创建过程中所导致的耦合过紧的问题。从而支持对象创建的稳定,它是接口抽象之后的第一步工作。
典型模式
- 工厂方法模式
- 抽象工厂模式
- 原型模式
- 构建器
原型模式
动机
在某些情况下,创建一个新对象的过程可能非常复杂或代价高昂。通过复制一个现有的对象(即原型),我们可以快速创建新的对象,并且可以对复制的对象进行独立修改。这种方式特别适用于需要频繁创建相似对象的场景。
结构
- Prototype(原型): 声明一个克隆自身的接口。
- ConcretePrototype(具体原型): 实现克隆方法,以便创建自己的副本。
- Client(客户端): 通过调用原型的克隆方法来创建新的对象。
代码推导
就是将工厂模式中的创建对象的接口,移到同一个类中,并进行深拷贝的方式创建对象
下面是一个简单的原型模式示例:
#include <iostream>
#include <string>
using namespace std;// Prototype Interface
class Prototype {
public:virtual Prototype* clone() const = 0;virtual void print() const = 0;virtual ~Prototype() {}
};// Concrete Prototype
class ConcretePrototype : public Prototype {
private:string field;public:ConcretePrototype(const string& field) : field(field) {}ConcretePrototype(const ConcretePrototype& other) : field(other.field) {}Prototype* clone() const override {return new ConcretePrototype(*this);}void print() const override {cout << "ConcretePrototype with field: " << field << endl;}
};// Client Code
int main() {ConcretePrototype prototype1("Value1");Prototype* prototype2 = prototype1.clone();prototype1.print();prototype2->print();delete prototype2;return 0;
}
在这个例子中,ConcretePrototype
实现了Prototype
接口并提供了一个clone
方法来复制自身。客户端代码通过调用clone
方法创建了一个ConcretePrototype
对象的副本。
应用
原型模式适用于以下场景:
- 当一个系统需要独立于其产品创建、构成和表示时。
- 当要实例化的类是由某个运行时动态加载的类时。
- 为了避免使用
new
操作符直接创建对象。 - 当一个类的实例化过程非常复杂或代价高昂时(如需要大量初始化资源)。
特点
- 优点:
- 可以在不暴露具体实现细节的情况下快速创建对象。
- 减少创建对象的成本(尤其是创建对象过程复杂或代价高昂时)。
- 允许动态增加或减少产品种类。
- 缺点:
- 需要为每一个类配备一个克隆方法,这可能会增加代码复杂性。
- 深拷贝和浅拷贝的实现需要仔细考虑,尤其是在涉及到复杂对象时。
要点总结
- 原型模式同样用于隔离类对象的使用者和具体类型之间的耦合关系,同样要求这些异变类拥有稳定的接口。
- 原型模式对于如何创建异变类的实体对象,采用原型克隆的方法来做。它使得我们可以非常灵活的动态创建。拥有某些稳定接口的新对象。所需工作仅仅是注册一个新类的对象即原型,然后在任何需要的地方克隆。
- 原型模式中的克隆方法可以利用某些框架中的序列化,来实现深拷贝。
原型模式与工厂方法模式对比
工厂方法模式
- 动机: 通过定义一个创建对象的接口,由子类决定实例化的类是哪一个。这样,工厂方法把实例化的过程推迟到子类。
- 优点: 避免了在客户端代码中显式使用
new
操作符,符合开闭原则。 - 应用场景: 适用于实例化的类可能经常变化的情况,通过工厂方法可以灵活地改变产品的实例化方式。
原型模式
- 动机: 通过复制现有对象来创建新对象,而不是通过类构造函数实例化对象。适用于需要频繁创建相似对象的场景。
- 优点: 可以快速创建对象,减少创建对象的成本。
- 应用场景: 适用于创建对象过程复杂或代价高昂,需要频繁创建相似对象的情况。
什么时候用什么模式
- 使用工厂方法模式: 当你需要将实例化过程推迟到子类并希望子类决定要创建的类是哪一个时。工厂方法模式通过继承和多态来实现对象的创建。
- 使用原型模式: 当你需要快速创建对象并且这些对象具有相似的属性时。原型模式通过克隆现有对象来实现对象的创建。
总的来说,如果对象创建过程复杂且创建开销大,或者对象是从一个繁重的构造函数生成的,那么使用原型模式更为合适。如果需要灵活地选择实例化的类并希望代码符合开闭原则,那么工厂方法模式是更好的选择。
相关文章:

设计模式11-原型模式
设计模式11-原型模式 写在前面对象创建模式典型模式原型模式动机结构代码推导应用特点要点总结 原型模式与工厂方法模式对比工厂方法模式原型模式什么时候用什么模式 写在前面 对象创建模式 通过对象创建模式绕开动态内存分配来避免创建过程中所导致的耦合过紧的问题。从而支…...
Tomcat长连接源码解析
长连接: 客户端发送Http请求至服务端,请求发送完之后socket连接不断开,可以继续接收下一个Http请求并且解析返回。接手并解析这些Http请求的时候socket连接不断开,这种过程被称为长连接。 需要注意的点就在于,在满足什么条件的情况…...
C++编程:实现一个跨平台安全的定时器Timer模块
文章目录 0. 概要1. 设计目标2. SafeTimer 类的实现2.1 头文件 safe_timer.h源文件 safe_timer.cpp 3. 工作流程图4. 单元测试 0. 概要 对于C应用编程,定时器模块是一个至关重要的组件。为了确保系统的可靠性和功能安全,我们需要设计一个高效、稳定的定…...

PyTorch的自动微分模块【含梯度基本数学原理详解】
文章目录 1、简介1.1、基本概念1.2、基本原理1.2.1、自动微分1.2.2、梯度1.2.3、梯度求导1.2.4、梯度下降法1.2.5、张量梯度举例 1.3、Autograd的高级功能 2、梯度基本计算2.1、单标量梯度2.2、单向量梯度的计算2.3、多标量梯度计算2.4、多向量梯度计算 3、控制梯度计算4、累计…...

AI 绘画|Midjourney设计Logo提示词
你是否已经看过许多别人分享的 MJ 咒语,却仍无法按照自己的想法画图?通过学习 MJ 的提示词逻辑后,你将能够更好地理解并创作自己的“咒语”。本文将详细拆解使用 MJ 设计 Logo 的逻辑,让你在阅读后即可轻松上手,制作出…...

LeNet实验 四分类 与 四分类变为多个二分类
目录 1. 划分二分类 2. 训练独立的二分类模型 3. 二分类预测结果代码 4. 二分类预测结果 5 改进训练模型 6 优化后 预测结果代码 7 优化后预测结果 8 训练四分类模型 9 预测结果代码 10 四分类结果识别 1. 划分二分类 可以根据不同的类别进行多个划分,以…...

【BUG】已解决:java.lang.reflect.InvocationTargetException
已解决:java.lang.reflect.InvocationTargetException 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发…...

配置kali 的apt命令在线安装包的源为国内源
目录 一、安装VMware Tools 二、配置apt国内源 一、安装VMware Tools 点击安装 VMware Tools 后,会加载一个虚拟光驱,里面包含 VMware Tools 的安装包 鼠标右键单击 VMware Tools 的安装包,点击复制到 点击 主目录,再点击选择…...

JAVA 异步编程(线程安全)二
1、线程安全 线程安全是指你的代码所在的进程中有多个线程同时运行,而这些线程可能会同时运行这段代码,如果每次运行的代码结果和单线程运行的结果是一样的,且其他变量的值和预期的也是一样的,那么就是线程安全的。 一个类或者程序…...

Golang | Leetcode Golang题解之第260题只出现一次的数字III
题目: 题解: func singleNumber(nums []int) []int {xorSum : 0for _, num : range nums {xorSum ^ num}lsb : xorSum & -xorSumtype1, type2 : 0, 0for _, num : range nums {if num&lsb > 0 {type1 ^ num} else {type2 ^ num}}return []in…...
IDEA自带的Maven 3.9.x无法刷新http nexus私服
问题: 自建的私服,配置了域名,使用http协议,在IDEA中或本地Maven 3.9.x会出现报错,提示http被blocked,原因是Maven 3.8.1开始,Maven默认禁止使用HTTP仓库地址,只允许使用HTTPS仓库地…...

56、本地数据库迁移到阿里云
现有需求,本地数据库迁移到阿里云上。 库名xy102表 test01test02test01 test023条数据。1、登录阿里云界面创建免费试用ECS实列。 阿里云登录页 (aliyun.com)](https://account.aliyun.com/login/login.htm?oauth_callbackhttps%3A%2F%2Fusercenter2.aliyun.com%…...

新时代多目标优化【数学建模】领域的极致探索——数学规划模型
目录 例1 1.问题重述 2.基本模型 变量定义: 目标函数: 约束条件: 3.模型分析与假设 4.模型求解 5.LINGO代码实现 6.结果解释 编辑 7.敏感性分析 8.结果解释 例2 奶制品的销售计划 1.问题重述 编辑 2.基本模型 3.模…...
单例模式详解
文章目录 一、概述1.单例模式2.单例模式的特点3.单例模式的实现方法 二、单例模式的实现1. 饿汉式2. 懒汉式3. 双重校验锁4. 静态内部类5. 枚举 三、总结 一、概述 1.单例模式 单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类…...
WebGIS主流的客户端框架比较|OpenLayers|Leaflet|Cesium
实现 WebGIS 应用的主流前端框架主要包括 OpenLayers、Leaflet、Mapbox GL JS 和 Cesium 等。每个框架都有其独特的功能和优势,适合不同的应用场景。 WebGIS主流前端框架的优缺点 前 端 框架优点缺点OpenLayers较重量级的开源库,二维GIS功能最丰富全面…...

【LabVIEW作业篇 - 2】:分数判断、按钮控制while循环暂停、单击按钮获取book文本
文章目录 分数判断按钮控制while循环暂停按钮控制单个while循环暂停 按钮控制多个while循环暂停单击按钮获取book文本 分数判断 限定整型数值输入控件值得输入范围,范围在0-100之间,判断整型数值输入控件的输入值。 输入范围在0-59之间,显示…...

Kafka架构详解之分区Partition
目录 一、简介二、架构三、分区Partition1.分区概念2.Offsets(偏移量)和消息的顺序3.分区如何为Kafka提供扩展能力4.producer写入策略5.consumer消费机制 一、简介 Apache Kafka 是分布式发布 - 订阅消息系统,在 kafka 官网上对 kafka 的定义…...

SSM之Mybatis
SSM之Mybatis 一、MyBatis简介1、MyBatis特性2、MyBatis的下载3、MyBatis和其他持久化层技术对比 二、MyBatis框架搭建三、MyBatis基础功能1、MyBatis核心配置文件2、MyBatis映射文件3、MyBatis实现增删改查4、MyBatis获取参数值的两种方式5、MyBatis查询功能6、MyBatis自定义映…...

Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)
Python list comprehension {列表推导式 - 列表解析式 - 列表生成式} 1. Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)2. Example3. ExampleReferences Python 中的列表解析式并不是用来解决全新的问题,只是为解决已有问题提供新的语法。 列…...
2024年7月12日理发记录
上周五天气还算好,不太热,晚上下班打车回家后,将目的地设置成日常去的那个理发店。 下车走到门口,熟悉的托尼帅哥正在抽烟,他一眼看到了我,马上掐灭烟头,从怀里拿出口香糖,咀嚼起来&…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...