创建型模式之原型模式

一、概述

1、工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程

2、通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立

3、核心思想:是通过复制现有对象的原型来创建对象,而不是通过实例化来创建对象。

二、原型模式的结构

原型模式包含以下3个角色

(1)Prototype(抽象原型类)

(2)ConcretePrototype(具体原型类)

(3)Client(客户类)

三、浅克隆与深克隆

1、浅克隆:当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制

 2、深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将被复制

四、模式优点 

1、简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率

2、扩展性较好

3、提供了简化的创建结构,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品

五、模式缺点

1、需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时,需要修改源代码,违背了开闭原则

2、在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来可能会比较麻烦

六、模式适用环境

1、创建对象成本较大,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改

2、系统要保存对象的状态,而对象的状态变化很小

3、需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少几个组合状态,通过复制原型对象得到新实列可能比使用构造函数创建一个新实例更加方便

七、原型模式示例代码

#include <iostream>
#include <map>
using namespace std;
class Prototype
{
public:
	virtual Prototype* clone() const = 0;
	virtual void showInfo() const = 0;
};

class Car : public Prototype
{
public:
	Car(const string& make, const string& model, int year)
		: m_make(make)
		, m_model(model)
		, m_year(year)
	{
	}

	void showInfo() const override
	{
		cout << m_year << " " << m_make << " " << m_model << endl;
	}

protected:
	Prototype* clone() const override
	{
		return new Car(m_make, m_model, m_year);
	}

private:
	string m_make;
	string m_model;
	int m_year;
};

class PrototypeFactory
{
public:
	Prototype* getPrototype(const string& type)
	{
		return m_prototypes[type]->clone();
	}

	void addPrototype(const string& type, Prototype* prototype)
	{
		m_prototypes[type] = prototype;
	}
private:
	map<string, Prototype*> m_prototypes;
};

int main()
{
	PrototypeFactory factory;

	Car* carPrototype = new Car("Honda", "Accord", 2024);
	factory.addPrototype("Car", carPrototype);

	Prototype* cloneCar = factory.getPrototype("Car");
	carPrototype->showInfo();
	cloneCar->showInfo();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟线程目前不推荐上生产的个人思考

1. pin 线程引发的问题比预期严重&#xff0c;需要修改的库繁多 截止目前 Java 21 虚拟线程一些比较严重的 Bug&#xff1a; 1. Thread.HoldsLock(Object) 这个方法&#xff0c;如果是虚拟线程调用&#xff0c;会在平台线程获取到锁之后&#xff0c;就算切换虚拟线程&#xf…

JavaScript闭包漏洞与修补措施

请先看下面一段代码 var obj (function () {var sonObj {a: 1,b: 2}return {get: function (v) {return sonObj[v]}}})()可以看出,这是一段很典型的js闭包代码,可以通过obj调用get方法传一个参数,如果传的是a就可以得到闭包内的对象sonObj.a var obj (function () {var sonO…

2024真正有效的苹果mac电脑清理工具CleanMyMac X

一、前言 对于Mac用户来说&#xff0c;电脑卡顿、运行缓慢无疑是一件令人头疼的事情。而市面上的清理软件又五花八门&#xff0c;效果参差不齐&#xff0c;如何才能找到一款真正有效的清理工具呢&#xff1f;今天&#xff0c;我们为大家推荐一款实力派电脑清理软件——CleanMy…

Canvs的js库:Fabric.js简单强大,用于绘制各种图形

Fabric.js是一个用于创建交互式的HTML5 Canvas应用程序的JavaScript库。它提供了一个简单而强大的API&#xff0c;用于在Web浏览器中绘制和操作图形对象。Fabric.js可以用于创建各种图形应用程序&#xff0c;例如绘图编辑器、图像编辑器、流程图、地图和数据可视化等。 官网文…

图像物体的边界- 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 给定一个二维数组M行N列&#xff0c;二维数组里的数字代表图片的像素&#xff0c;为了简化问题&#xff0c;仅包含像素1和5两种像素&#xff0c;每种像素代表一个…

C语言中的字符魔法:大小写转换的艺术

引言 在C语言的世界里&#xff0c;字符处理是一项基础且重要的任务。字符作为编程中最基本的元素之一&#xff0c;承担着信息展示、数据交互等多重角色。特别是在处理文本信息时&#xff0c;字符的转换和识别显得尤为重要。大小写字母的转换就是其中一个常见的需求&#xff0c…

STM32作为SPI slave与主机异步通信

背景 最近被测试提了个BUG&#xff0c;说某款产品在用户按下前面板的按键后&#xff0c;对应的按键灯没有亮起来。前面板跟主机是通过SPI口通信&#xff0c;前面板是从机&#xff0c;从机想要主动发送消息&#xff0c;需要通过GPIO中断来通知主机&#xff1a; 上图前面板是ST…

flurl升级之后没有FlurlNewtonsoftJsonSerializer

新建NewtonsoftJsonSerializer.cs /// <summary> /// ISerializer implementation based on Newtonsoft.Json. /// Default serializer used in calls to GetJsonAsync, PostJsonAsync, etc. /// </summary> public class NewtonsoftJsonSerializer : IJsonSerial…

【CSP试题回顾】202312-1-仓库规划

CSP-202312-1-仓库规划 解题思路 定义结构体和变量&#xff1a; 结构体 MyWareHouse&#xff0c;用来存储每个仓库的索引&#xff08;编号&#xff09;和位置编码。定义了整数 n 和 m&#xff0c;分别代表仓库的数量和位置编码的维数。定义了一个 vector<MyWareHouse> 的…

图解Vivado工程的目录结构

一、目录结构 ​在使用Vivado进行工程设计时&#xff0c;创建工程以及运行工程的过程中都会生成大量的目录和文件&#xff0c;下面图将对目录和文件结构及功能进行一个简单说明。 工程示例图 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 二、参考资料…

ShardingJdbc分库分表-浅谈分表原理

文章目录 为什么要分库分表一、分库分表二、不停机分库分表数据迁移 为什么要分库分表 一般的机器&#xff08;4核16G&#xff09;&#xff0c;单库的MySQL并发&#xff08;QPSTPS&#xff09;超过了2k&#xff0c;系统基本就完蛋了。最好是并发量控制在1k左右。这里就引出一个…

kubesphere jenkins 流水线 未运行(解决方案)

场景&#xff1a; 在kubesphere 中运行 流水线 devops 结果&#xff0c;显示未运行 但是用 admin 账户是可以运行成功的。 问题解决 1- 查日志&#xff1a; 然后 Caused: org.acegisecurity.userdetails.UsernameNotFoundException: org.springframework.security.core.…

JVM运行时数据区——运行时数据区及线程概述

文章目录 1、运行时数据区概述2、线程3、小结 内存是非常重要的系统资源&#xff0c;是硬盘和CPU的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM在程序执行期间把它所管理的内存分为若干个不同的数据区域。这些不同的数据区域可以分为两种类型&#xff…

吴恩达机器学习全课程笔记第六篇

目录 前言 P96-P100 使用多个决策树 随机森林算法 XGBoost 什么时候使用决策树 P101-P107 聚类 K-means 初始化K-means 选择聚类的个数 P108-P113 异常检测算法 开发和评估异常检测系统 异常检测vs监督学习 选择要使用的特征 前言 这是吴恩达机器学习笔记的第…

【嵌入式实践】【芝麻】【设计篇-2】从0到1给电动车添加指纹锁:项目可行性分析

0. 前言 该项目是基于stm32F103和指纹模块做了一个通过指纹锁控制电动车的小工具。支持添加指纹、删除指纹&#xff0c;电动车进入P档等待时计时&#xff0c;计时超过5min则自动锁车&#xff0c;计时过程中按刹车可中断P档状态&#xff0c;同时中断锁车计时。改项目我称之为“芝…

基于反光柱特征的激光定位算法思路

目录 1. 识别反光柱2. 数据关联2.1 基于几何形状寻找匹配2.2 暴力寻找匹配 3. 位姿估计&#xff08;最小二乘求解&#xff09;4. 问题4.1 精度问题4.2 快速旋转时定位较差 1. 识别反光柱 反光柱是特殊材料制成&#xff0c;根据激光雷达对反光材料扫描得到的反射值来提取特征。…

如何解决微服务的数据一致性分发问题?

介绍 系统架构微服务化以后,根据微服务独立数据源的思想,每个微服务一般具有各自独立的数据源,但是不同微服务之间难免需要通过数据分发来共享一些数据,这个就是微服务的数据分发问题。Netflix/Airbnb等一线互联网公司的实践[参考附录1/2/3]表明,数据一致性分发能力,是构…

京东云硬钢阿里云:承诺再低10%

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 阿里云刚刚宣布史上最大规模的全线产品降价20%&#xff0c;这热度还没过&#xff0c;京东云当晚就喊话&#xff1a;“随便降、比到底!&#xff0c;全网比价&#xff0c;击穿低价&#xff0c;再低10%”&#xff0c;并…

求最短路径之BF算法

介绍 全称Bellman-Ford算法&#xff0c;目的是求解有负权边的最短路径问题。 考虑环&#xff0c;根据环中边的边权之和的正负&#xff0c;将环分为零环、正环、负环。其中零环、正环不会影响最短路径的求解&#xff0c;而负环会影响最短路径的求解。 可用BF算法返回一个bool值…

Redis之十:Spring Data Redis --- CrudRepository方式

SpringData Redis CrudRepository方式 Spring Data Redis 的 CrudRepository 是 Spring Data 框架中用于提供基础 CRUD&#xff08;创建、读取、更新和删除&#xff09;操作的一个接口。在与 Redis 集成时&#xff0c;尽管 Redis 是一个键值存储系统&#xff0c;并没有像关系型…