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

【Python笔记-设计模式】原型模式

一、说明

原型模式是一种创建型设计模式, 用于创建重复的对象,同时又能保证性能。

使一个原型实例指定了要创建的对象的种类,并且通过拷贝这个原型来创建新的对象。

(一) 解决问题

主要解决了对象的创建与复制过程中的性能问题。主要针对:复杂对象相识对象的创建

在某些情况下,直接使用new关键字或者其他方式创建对象可能会导致性能损耗较大,特别是当对象的创建过程比较复杂或者耗时时。

(二) 使用场景

  • 类初始化时需要消耗大量资源,如数据、硬件资源等。通过原型拷贝可以避免这些消耗,提高资源利用率。
  • 创建对象时需要繁琐的数据准备或访问权限。原型模式可以简化对象的创建过程,提高性能。
  • 一个对象需要提供给其他对象访问,并且各个调用者可能需要修改其值。通过保护性拷贝,可以创建多个对象供调用者使用,同时保持原对象的状态不变。

二、结构

  1. 原型(Prototype):接口将对克隆方法进行声明。在绝大多数情况下,其中只会有一个名为clone克隆的方法。
  2. 具体原型(Concrete Prototype):类将实现克隆方法。除了将原始对象的数据复制到克隆体中之外,该方法有时还需处理克隆过程中的极端情况,例如克隆关联对象和梳理递归依赖等等。
  3. 客户端(Client):可以复制实现了原型接口的任何对象。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。例:通过原型实例克隆多个人的对象,并更新其属性
"""import copyclass Prototype:def __init__(self):self._objs = {}def register_object(self, key, obj):self._objs[key] = objdef unregister_object(self, key):del self._objs[key]def clone(self, key, **attrs):obj = copy.deepcopy(self._objs[key])obj.__dict__.update(attrs)return objclass People:def __init__(self, name: str, age: int):self.name = nameself.age = agedef __str__(self):return f"{self.__dict__}"if __name__ == '__main__':"""Original: {'name': '张三', 'age': 20}Clone: {'name': '李四', 'age': 24}"""# 创建原型对象prototype = Prototype()# 创建一个 People 实例并注册为原型对象people = People(name="张三", age=20)prototype.register_object("people", people)# 克隆一个 People 实例people_clone = prototype.clone("people", name="李四", age=24)# 输出原型对象和克隆对象print("Original:", people)print("Clone:", people_clone)

四、优缺点

优点

  • 性能提升:通过复用已有对象,避免了重复的对象创建和初始化过程,从而提高了性能。
  • 简化创建过程:客户端代码无需知道对象创建的细节,只需要调用克隆方法即可。

缺点

  • 复杂度增加:需要实现克隆方法
  • 深拷贝和浅拷贝问题:在实现克隆方法时,需要考虑深拷贝和浅拷贝的问题。浅拷贝只复制对象本身和其中的基本数据类型,而深拷贝会复制对象及其引用的所有对象。如果处理不当,可能会导致对象之间的意外关联或修改。

 跳转主页:【Python笔记】设计模式-CSDN博客

http://www.lryc.cn/news/305650.html

相关文章:

  • 启动node服务报错Error: listen EACCES: permission denied 0.0.0.0:5000
  • onlyoffice api开发
  • 设计模式-工厂方法模式(C++)
  • ThreeJS 几何体顶点position、法向量normal及uv坐标 | UV映射 - 法向量 - 包围盒
  • 基于SpringBoot的家教管理系统
  • 简单mock server模拟用户请求给小程序提供数据
  • 【MATLAB】 EWT信号分解+FFT傅里叶频谱变换组合算法
  • MATLAB中,如何捕获和处理异常?如何在MATLAB中自定义错误消息?在MATLAB中,error函数和warning函数有什么区别?
  • 【算法与数据结构】127、LeetCode单词接龙
  • CAN——创建一个数据库DBC文件
  • (十三)【Jmeter】线程(Threads(Users))之tearDown 线程组
  • MySQL数据库基础(十三):关系型数据库三范式介绍
  • 掌控互联网脉络:深入解析边界网关协议(BGP)的力量与挑战
  • Vue2页面转化为Vue3
  • 【课程作业】提取图中苹果的面积、周长和最小外接矩形的python、matlab和c++代码
  • 解决easyExcel模板填充时转义字符\{xxx\}失效
  • 在项目中使用CancelToken选择性取消Axios请求
  • [c++] 记录一次引用使用不当导致的 bug
  • 能不能节约百分之九十的算力来训练模型
  • LeetCode206: 反转链表.
  • 高级统计方法 第1次作业
  • spinalhdl,vivado,fpga
  • Tomcat线程池原理(下篇:工作原理)
  • 【服务器数据恢复】通过reed-solomon算法恢复raid6数据的案例
  • LeetCode 2583.二叉树中的第 K 大层和:层序遍历 + 排序
  • element ui 安装 简易过程 已解决
  • websoket
  • 案例:微服务从Java/SpringBoot迁移到Golan
  • 小波变换模拟
  • cv::Mat图像操作