创建型模式 (Python版)

单例模式

懒汉式

class SingleTon:# 类属性_obj = None  # 用来存储对象# 创造对象def __new__(cls, *args, **kwargs):# 如果对象不存在,就创造一个对象if cls._obj is None:cls._obj = super().__new__(cls, *args, *kwargs)# 返回对象return cls._objif __name__ == '__main__':obj_1 = SingleTon()  # 创造一个对象obj_2 = SingleTon()  # 再次创造一个对象print("obj_1的内存地址:", id(obj_1))  # obj_1的内存地址: 2801491317584print("obj_2的内存地址:", id(obj_2))  # obj_2的内存地址: 2801491317584print(obj_1 is obj_2)  # True

饿汉式

  • test.py
class SingleTon:pass# 创建一个对象
obj = SingleTon# 提供接口
def get_instance():return obj
  • main.py
from test import get_instanceif __name__ == '__main__':obj_1 = get_instance()  # 创建一个对象obj_2 = get_instance()  # 再创建一个对象print(obj_1 is obj_2)  	# True

工厂模式

简单工厂模式

"""实现:简单计算器(加减乘除)1. 提供一个抽象产品类2. 提供多个具体产品类3. 提供一个工厂类
"""from abc import ABC, abstractmethod# 计算器(抽象产品类)
class Calculator(ABC):  # 继承 ABC 抽象类def __init__(self):self.left_value = 0self.right_value = 0def set(self, left_value, right_value):self.left_value = left_valueself.right_value = right_valuereturn self@abstractmethoddef run(self):  # 抽象方法pass# 加法计算器(具体产品类)
class AddCalculator(Calculator):  # 继承 Calculator 类def run(self):return self.left_value + self.right_value# 减法计算器(具体产品类)
class SubCalculator(Calculator):  # 继承 Calculator 类def run(self):return self.left_value - self.right_value# 乘法计算器(具体产品类)
class MulCalculator(Calculator):  # 继承 Calculator 类def run(self):return self.left_value * self.right_value# 除法计算器(具体产品类)
class DivCalculator(Calculator):  # 继承 Calculator 类def run(self):if self.right_value == 0:raise "除数不能为零!"return self.left_value / self.right_value# 工厂类
class Factory:@staticmethoddef produce_calculator(char):  # 类方法match char:case "+":return AddCalculator()  # 创建对象case "-":return SubCalculator()  # 创建对象case "*":return MulCalculator()  # 创建对象case "/":return DivCalculator()  # 创建对象case _:raise "不支持其他的运算符!"if __name__ == '__main__':# 工厂生产4种类型的计算器产品add_calculator = Factory.produce_calculator("+")  # 加法计算器sub_calculator = Factory.produce_calculator("-")  # 减法计算器mul_calculator = Factory.produce_calculator("*")  # 乘法计算器div_calculator = Factory.produce_calculator("/")  # 除法计算器# 使用除法计算器res = div_calculator.set(10, 5).run()  # 设置左值(被除数)和右值(除数),然后运行print(res)  # 2.0

工厂方法模式

from abc import ABC, abstractmethod# 产品(抽象产品类)
class Product(ABC):  # 继承 ABC 抽象类# 抽象:此产品补充燃料的功能@abstractmethoddef fuel(self):pass# 抽象:此产品起飞的功能@abstractmethoddef fly(self):pass# 飞机(具体产品类)
class PlaneProduct(Product):  # 继承 Product 产品类# 实现:此产品补充燃料的功能def fuel(self):print(f"飞机-CS{id(self)},补充燃料中...")# 实现:此产品起飞的功能def fly(self):print(f"飞机-CS{id(self)},起飞!")# 火箭(具体产品类)
class RocketProduct(Product):  # 继承 Product 产品类# 实现:此产品补充燃料的功能def fuel(self):print(f"火箭-CS{id(self)},补充燃料中...")# 实现:此产品起飞的功能def fly(self):print(f"火箭-CS{id(self)},起飞!")# 工厂(抽象工厂类)
class Factory(ABC):# 抽象:生产产品@abstractmethoddef produce_product(self):pass# 飞机工厂(具体工厂类)
class PlaneFactory(Factory):# 具体:生产飞机产品def produce_product(self):return PlaneProduct()  # 创建对象,并返回出去# 火箭工厂(具体工厂类)
class RocketFactory(Factory):# 具体:生产火箭产品def produce_product(self):return RocketProduct()  # 创建对象,并返回出去# 演示
def work(factory):product = factory.produce_product()  # 工厂生产产品product.fuel()  # 使用产品的"补充燃料"功能product.fly()  # 使用产品"飞行"的功能if __name__ == '__main__':# 创建一个飞机工厂plane_factory = PlaneFactory()# 让飞机工厂干活work(plane_factory)# 创建一个火箭工厂rocket_factory = RocketFactory()# 让火箭工厂干活work(rocket_factory)

抽象工厂模式

from abc import ABC, abstractmethod# 抽象产品
class Product(ABC):@abstractmethoddef show(self):pass# 抽象键盘产品
class KeyBoard(Product):@abstractmethoddef show(self):pass# 抽象鼠标产品
class Mouse(Product):@abstractmethoddef show(self):pass# 具体键盘产品1
class MikaKeyBoard(KeyBoard):def show(self):print("Mika键盘")# 具体键盘产品2
class PikiKeyBoard(KeyBoard):def show(self):print("Piki键盘")# 具体鼠标产品1
class MikaMouse(Mouse):def show(self):print("Mika鼠标")# 具体鼠标产品2
class PikiMouse(Mouse):def show(self):print("Piki鼠标")# 抽象工厂类
class Factory(ABC):@abstractmethoddef produce_keyboard(self):pass@abstractmethoddef produce_mouse(self):pass# 具体工厂1
class MikaFactory(Factory):def produce_keyboard(self):return MikaKeyBoard()def produce_mouse(self):return MikaMouse()# 具体工厂2
class PikiFactory(Factory):def produce_keyboard(self):return PikiKeyBoard()def produce_mouse(self):return PikiMouse()# 测试
def work(factory):keyborad = factory.produce_keyboard()  # 工厂制作键盘mouse = factory.produce_mouse()  # 工厂制作鼠标keyborad.show()  # 查看键盘信息mouse.show()  # 查看鼠标信息if __name__ == '__main__':# 创造Mika工厂,让它运行工作factory = MikaFactory()work(factory)# 创建Piki工厂,让它运行工作factory = PikiFactory()work(factory)

建造者模式

"""小明想要给自己的"戴尔"电脑外接一些设备:Mika鼠标、Piki键盘小花想要给自己的"联想"电脑外接一些设备:Piki鼠标、Mika键盘1. 找到技术人员告诉需求2. 技术员工进行组装3. 检查组装情况
"""from abc import ABC, abstractmethod# 组装电脑(抽象)
class AssembleComputer(ABC):@abstractmethoddef install_mouse(self, brand):  # 安装鼠标(抽象)pass@abstractmethoddef install_keyboard(self, brand):  # 安装键盘(抽象)pass@abstractmethoddef show(self):  # 查看组装的状态(抽象)pass# 组装"戴尔"电脑(具体)
class AssembleDellComputer(AssembleComputer):def __init__(self):self.__installation_list = []  # 安装列表,用来记录当前已经成功安装了的组件def install_mouse(self, brand):self.__installation_list.append(f"{brand}鼠标")print(f"已安装:{brand}鼠标")def install_keyboard(self, brand):self.__installation_list.append(f"{brand}键盘")print(f"已安装:{brand}键盘")def show(self):print("此电脑的所有外接设备:", end="")for item in self.__installation_list:print(item, end=", ")print()# 组装"联想"电脑(具体)
class AssembleLenovoComputer(AssembleComputer):def __init__(self):self.__installation_list = []  # 安装列表,用来记录当前已经成功安装了的组件def install_mouse(self, brand):self.__installation_list.append(f"{brand}鼠标")print(f"已安装:{brand}鼠标")def install_keyboard(self, brand):self.__installation_list.append(f"{brand}键盘")print(f"已安装:{brand}键盘")def show(self):print("此电脑的所有外接设备:", end="")for item in self.__installation_list:print(item, end=", ")print()# 建造者(抽象)
class Builder(ABC):def __init__(self, computer_type):# self.product 里面保存(维护)着一个组装对象if computer_type == "戴尔":self._product = AssembleDellComputer()elif computer_type == "联想":self._product = AssembleLenovoComputer()else:raise "电脑类型错误!"@abstractmethoddef install_mouse(self, brand):pass@abstractmethoddef install_keyboard(self, brand):pass@abstractmethoddef check(self):pass# 建造者(具体)————技术人员
class Technician(Builder):# 技术人员安装鼠标def install_mouse(self, brand):print(f"技术人员正在安装{brand}鼠标...")self._product.install_mouse(brand)print(f"技术人员安装{brand}鼠标成功!")# 技术人员安装键盘def install_keyboard(self, brand):print(f"技术人员正在安装{brand}键盘...")self._product.install_keyboard(brand)print(f"技术人员安装{brand}键盘成功!")# 技术人员检查安装情况def check(self):print("技术人员正在检查设备的安装情况...")print("技术人员检查完毕,安装结果如下:")self._product.show()if __name__ == '__main__':# 创造一个负责组装戴尔电脑的技术人员t1 = Technician("戴尔")# 创造一个负责组装联想电脑的技术人员t2 = Technician("联想")# 小明告诉 t1 技术人员,组装 Mika鼠标、Piki键盘,技术人员根据要求进行安装t1.install_mouse("Mika")t1.install_keyboard("Piki")# 小花告诉 t2 技术人员,组装 Piki鼠标、Mika键盘,技术人员根据要求进行安装t2.install_mouse("Piki")t2.install_keyboard("Mika")# t1 技术人员检查组装情况t1.check()# t2 技术人员检查组装情况t2.check()

原型模式

import copy  # 导入copy模块,用于深度复制对象# 定义一个名为 Prototype(原型)的类,用于管理对象的注册、注销和克隆
class Prototype:def __init__(self):self._objects = {}  # 初始化一个字典来存储注册的对象,键为名称,值为对象实例def register_object(self, name, obj):"""  注册一个对象到_objects字典中  :param name: 对象的名称  :param obj: 要注册的对象实例  """self._objects[name] = objdef unregister_object(self, name):"""  从_objects字典中注销一个对象  :param name: 要注销的对象的名称  """del self._objects[name]def clone(self, name, **attr):"""  克隆一个已注册的对象,并更新其内部属性字典  :param name: 要克隆的对象的名称  :param attr: 要更新的属性字典,使用关键字参数传入  :return: 克隆并更新后的对象实例  """obj = copy.deepcopy(self._objects.get(name))  # 使用deepcopy进行深度复制,得到一个新的对象实例obj.__dict__.update(attr)  # 更新对象的__dict__属性,即更新其内部属性。  attr == {'a': 1, 'b': 2, 'c': 3}return objdef test():# 定义一个类A,用于演示class A:def __str__(self):return "I am A"# 创建A的一个实例aa = A()# 创建一个Prototype实例,用于管理对象prototype = Prototype()# 将a注册到prototype中,名称为'a'prototype.register_object('a', a)# 克隆a并更新其内部属性,得到bb = prototype.clone('a', a=1, b=2, c=3)# 打印a的字符串表示print(a)# 打印b的内部属性字典print(b.__dict__)# 尝试打印b的属性a, b, cprint(b.a)print(b.b)print(b.c)if __name__ == '__main__':test()

补充说明

  • 原型模式(Prototype Pattern)是一种创建型设计模式,它允许一个对象通过复制其自身的内部状态来创建新的对象实例。

  • 这种复制过程可以被称为“克隆”。

  • 原型模式提供了一种不依赖于类的构造函数来创建对象实例的方式,而是使用现有的对象实例来创建新的对象。

原型模式的作用

  1. 性能优化:当对象的创建过程非常复杂或者代价非常高时,使用原型模式可以避免重复执行这些复杂的操作,从而提高性能。通过克隆一个已经存在的对象,可以快速地生成新的对象实例。
  2. 避免子类的构造函数被频繁调用:在继承层次较深的场景下,频繁地调用子类的构造函数可能会带来性能问题。通过原型模式,可以避免这种情况,因为对象的创建是通过克隆来完成的。
  3. 动态扩展:由于原型模式允许在运行时动态地添加或删除对象,因此它可以支持动态扩展。这意味着可以根据需要动态地改变系统中对象的数量或类型。
  4. 简化对象创建:当对象创建涉及复杂的配置或设置时,原型模式可以提供一个更简单的创建对象的方式。通过克隆一个已经配置好的对象实例,可以快速地生成具有相同配置的新对象。

示例代码中的原型模式

  • 在示例代码中,Prototype类就是一个原型管理器的实现。
  • 它维护了一个存储已注册对象的字典(_objects)。
  • 通过register_object()方法可以将对象注册到字典中,通过unregister_object()方法可以从字典中注销对象。
  • clone()方法则用于克隆已注册的对象,并允许通过关键字参数来更新克隆对象的属性。
  • 这个示例代码中的A类是一个简单的类,用于演示原型模式的使用。
  • 通过创建一个A类的实例a,并将其注册到Prototype实例中,然后调用clone()方法来克隆a并更新其属性,可以得到一个新的对象实例b
  • 这个过程中,ab是独立的对象实例,但它们具有相同的初始状态(因为ba的克隆),并且b的属性可以被单独更新。

总结

创建型模式总结

  • 单例模式:创建一个全局的对象
  • 工厂方法模式:实现单个类的对象的创建
  • 抽象工厂模式:实现多个类的对象的创建
  • 建造者模式:实现复杂类的对象的创建
  • 原型模式:实现自身类的克隆

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

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

相关文章

OpenAI宫斗剧番外篇: “Ilya与Altman联手对抗微软大帝,扫除黑恶势力”,“余华”和“莫言”犀利点评

事情是这样的。 小编我是一个重度的智谱清言用户,最近智谱清言悄悄上线了一个“划词引用”功能后,我仿佛打开了新世界的大门。我甚至用这个小功能,玩出来了即将为你上映的《OpenAI宫斗剧番外篇》。 3.5研究测试:hujiaoai.cn 4研…

@Controller和@RestController区别

一、Controller 注解: Controller 注解用于定义一个控制器类,通常配合 Spring MVC 框架使用。 控制器类负责处理用户的 HTTP 请求,并将处理结果返回给客户端。 控制器类中的方法通常通过 RequestMapping 或其衍生注解来映射特定的 URL 请求…

Python中的数据类型转换

文章目录 一、转成整数形式二、转成浮点数形式三、转成字符串形式四、转成列表形式五、转成元祖形式六、json和字典转换1.json转字典2.字典转json 一、转成整数形式 使用int()方法,示例代码如下: a 5201314 result int(a) print(result) print(type(…

蓝牙Classic加密算法设计和实现,SAFER+,E0,E1,E2,E3(python)

概述 之前用python给大家实现了所有LE相关加密工具算法。bobwenstudy/BluetoothCryptographicToolbox: LE SMP加密算法设计和实现(python) (github.com),最近重温了下Classic加密,顺便将Classic所有加密算法给实现了一遍。 在蓝牙Classic Spec中&#…

5.14.3 UNETR:用于 3D 医学图像分割的 Transformers

具有收缩和扩展路径的全卷积神经网络 (FCNN) 在大多数医学图像分割应用中表现出了突出的作用。在 FCNN 中,编码器通过学习全局和局部特征以及上下文表示来发挥不可或缺的作用,这些特征和上下文表示可用于解码器的语义输出预测。 在FCNN中,收缩…

对列表进行统计和计算

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python的列表提供了内置的一些函数来实现统计、计算的功能。下面介绍几种常用的功能。 (1)获取指定元素出现的次数 使用列表…

数字水印 | 图像标准化论文:Digital Watermarking Robust to Geometric Distortions(二)

目录 C 变换参数的确定D 水印的影响E 可替代的标准化过程 🤖原文: Digital Watermarking Robust to Geometric Distortions 🤖前言: 这是一篇 2005 年的 SCI 一区 CCF-A,但是网上关于它的讲解貌似挺少的。文中提出…

智能车竞赛指南:从零到一,驶向自动驾驶的未来

智能车竞赛指南:从零到一,驶向自动驾驶的未来 一、智能车竞赛概览1.1 竞赛介绍1.2 竞赛分类 二、智能车开发技术基础2.1 硬件平台2.2 软件开发 三、实战案例:循线小车开发3.1 系统架构3.2 代码示例 四、技术项目:基于ROS的视觉导航…

FedSyn: Synthetic Data Generation using Federated Learning

arxiv2022,没找到是哪个刊物的,是没投中吗? 这篇是用GAN做数据生成,每个client都训练一个生成器,加噪声传到server端聚合,实验是衡量生成图片的质量。 论文地址:arxiv code:没找到 贡献 提出了提出了一种新颖的方法(FedSyn ),将联邦学习、使用 GAN的合成数据生成…

高中数学:平面向量-数量积(向量与向量的乘积)与投影

一、引题 物理上的力做功 二、数量积与投影 1、数量积 θ的范围是[0,π] 2、投影 向量的投影,依然是一个向量! 3、运算法则 易错点: 4、重要性质 这里对性质(2)要注意一下:如果 a → \mathop{a}\limits ^{\rightarrow…

AWS安全性身份和合规性之Shield

shield:盾(牌);(保护机器和操作者的)护罩,防护屏,挡板;屏障;保护物;(警察的)盾形徽章;保护人;掩护物;盾形纹徽;盾形奖牌; AWS Shield是一项AWS托管的DDoS(Distributed Denial of Service,分布式…

建模:Maya

一、常用按键 1、alt 左键 —— 环绕查看 2、alt 中键 —— 拖动模型所在面板 3、空格 —— 进入三视图模式;空格 左键按住拖动 —— 切换到对应视图 二、骨骼归零 1、T Pose 旋转模式,点击模型,摆好T姿势即可 2、复制模型设置200距离…

[AIGC] Java CompletableFuture:简介及示例

Java 8 引入了一个名为 CompletableFuture 的新库,正如其名称所示,该库提供了一种名为 “Completable Future” 的新 API,其主要目的是支持异步编程,并通过可搜索的操作将这些异步操作进行聚合管控。 文章目录 CompletableFuture …

LeetCode热题100—普通数组

53.最大子数组和 题目 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2…

【Linux】进程信号及相关函数/系统调用的简单认识与使用

文章目录 前言一、相关函数/系统调用1. signal2. kill3. abort (库函数)4. raise (库函数)5. alarm 前言 现实生活中, 存在着诸多信号, 比如红绿灯, 上下课铃声…我们在接收到信号时, 就会做出相应的动作. 对于进程也是如此的, 进程也会收到来自 OS 发出的信号, 根据信号的不同…

【ARM 嵌入式 C 入门及渐进 6.1 -- ARMv8 C 内嵌汇编写系统寄存器的函数实现】

请阅读【嵌入式开发学习必备专栏】 文章目录 ARMv8 C 内嵌汇编写系统寄存器 ARMv8 C 内嵌汇编写系统寄存器 在ARMv8架构下,使用C语言结合内嵌汇编实现将一个值写入特定系统寄存器的函数可以按照下面的方法进行。 下面这个示例展示了如何将一个uint64_t类型的值写入…

[OpenGL] 法线贴图

目录 一 为什么要使用法线贴图 二 二种不同法线方式的使用 2.1 插值法线 2.1 法线贴图 本章节源码 点击此处 一 为什么要使用法线贴图 法线贴图我们可以使用更少的顶点表现出同样丰富的细节。高精度网格和使用法线贴图的低精度网格几乎区分不出来。所以法线贴图不仅看起来…

UE5中搭建一个简单的海岛

本文将用UE的WaterSystem与地形搭建一个简单的海岛,通过WaterSystem的参数设置,可以更好的自定义海岸线等效果。 1.基础风貌 1.1.首先新建一个Basic基础场景,切换到地形编辑模式刷出一块高地,用于沙滩。 1.2.引入UE官方插件Wat…

[IMX6ULL驱动开发]-Linux对中断的处理(一)

目录 中断概念的引入 ARM架构中断的流程 异常向量表 Linux系统对中断的处理 ARM对程序和中断的处理 Linux进程中断处理 中断概念的引入 如何理解中断,我们可以进行如下抽象。把CPU看做一个母亲,当它正在执行任务的时候,可以看为是一个母…

【BSP开发经验】简易文件系统digicapfs实现方式

文章目录 背景Linux vfs框架介绍数据结构系统调用openwriteread 总体框架 Linux 磁盘高速缓存机制标准文件访问同步文件访问异步文件访问buffer_head 如何实现一个简单的文件系统blkdevfs注册文件系统产生一个文件让文件变得可读可写 背景 在新的分区升级启动方案中需要分别实…