首页 > 编程语言 >Python实现软件设计模式5:原型模式 Prototype Pattern

Python实现软件设计模式5:原型模式 Prototype Pattern

时间:2023-12-20 12:13:23浏览次数:26  
标签:__ 克隆 Python Pattern self 模式 对象 print display

动机

  • 对象的克隆问题,想要复制出本对象的一个副本,属性方法一模一样
  • 从需求上来说,先快速克隆对象,后续根据需求再进行对象局部属性的修改
  • 区分为深克隆和浅克隆两个版本,默认为浅克隆

角色

  • Prototype 抽象原型类
  • Concrete Prototype 具体原型类
  • Client 客户类

浅克隆与深克隆


模式实例

邮件对象包含多项内容,如发送者、接收者、标题、内容、日期、附件等,系统需要提供一个右键复制功能,对于已有的邮件对象,可以通过复制的方式创建一个新的邮件对象,如果需要改变某部分内容,无需修改原始的邮件对象,只需要修改复制后得到的邮件对象即可。

其中,将附件内容定义为一个引用对象(C/C++语义下的指针类型,或Python语义下的可变对象如列表),代码设计浅克隆和深克隆两个版本。

代码

import copy
from abc import ABC,abstractmethod

class Prototype(ABC):    # 抽象类,声明对象的克隆接口
    @abstractmethod
    def clone(self):    # 返回一个类型为自己的对象
        pass

class Email_S(Prototype):   # shallow copy 
    def __init__(self, sd, rp, tt, date, msg, apd):
        self.sender = sd
        self.recipient = rp
        self.title = tt
        self.date = date
        self.message = msg
        self.appendix = apd     # list

    def clone(self):    # 浅克隆对象
        return copy.copy(self)
    
    def display(self):
        print('-'*50)
        print(f"  Time  : {self.date}    Title:{self.title}")
        print(f" Sender : {self.sender}" + ' '*18 + f"Recipient:{self.recipient}")
        print(f" Message: {self.message}")
        print(f"Appendix: {self.appendix}")
        print('-'*50)
    
    def getAppendix(self):
        return self.appendix

class Email_D(Prototype):   # deep copy
    def __init__(self, sd, rp, tt, date, msg, apd):
        self.sender = sd
        self.recipient = rp
        self.title = tt
        self.date = date
        self.message = msg
        self.appendix = apd     # list

    def clone(self):    # 深克隆对象
        return copy.deepcopy(self)
    
    def display(self):
        print('+'*50)
        print(f"  Time  : {self.date}    Title:{self.title}")
        print(f" Sender : {self.sender}" + ' '*18 + f"Recipient:{self.recipient}")
        print(f" Message: {self.message}")
        print(f"Appendix: {self.appendix}")
        print('-'*50)

if __name__ == '__main__':
    mail1 = Email_S('Alice', 'Bob', 'Marry Me', '2023-12-12 10:00:00', 'I like you very much, please be my wife!', [1,2,3])
    _mail1 = mail1.clone()  # 浅克隆一份

    # mail1.display()
    # _mail1.display()

    mail1.appendix.append(400)  # 修改源对象的引用类型附件对象

    mail1.display() 
    _mail1.display()        # 浅拷贝后可变对象的值也一样

    print("\n")

    mail2 = Email_D('Bob', 'Alice', 'Reply', '2023-12-12 11:00:00', 'Fxxk you, gun ni ma de :) ', [4,5,6])
    _mail2 = mail2.clone()  # 深克隆一份

    # mail2.display()
    # _mail2.display()

    mail2.appendix.append(700)  # 修改源对象的引用类型附件对象

    mail2.display()         # 深拷贝后可变对象的值不一样
    _mail2.display()

总结

  • 优化对象创建过程,通过复制一个已有实例可以提高新实例的创建效率
  • 扩展性好,无需专门的工厂类来创建产品
  • 需要为每一个类配备一个克隆方法(继承Prototype并重写clone方法),当对一个类进行改造时,需要修改、扩展源代码,违背开闭原则
  • 可以保存对象的状态,以便在需要的时候使用,可以辅助实现动作行为撤销操作(这时需要使用深克隆的方式)
  • 要避免使用分层次的工厂类来创建分层次的对象

标签:__,克隆,Python,Pattern,self,模式,对象,print,display
From: https://www.cnblogs.com/Higgerw/p/17916242.html

相关文章

  • 基于SaaS模式的云HIS信息管理系统源码
    云HIS全称为基于云计算的医疗卫生信息系统,是运用云计算大数据、物联网等新兴信息技术,按照现代医疗卫生管理要求,在一定区域范围内以数字化形式提供医疗卫生行业数据收集、存储、传递处理的业务和技术亚台云HIS系统采用主流成熟技术开发,软件结构简洁、代码规范易阅读,SaaS应用,全......
  • 适配器模式
    在你成功拿到五心之钢后,为了能够好好玩这把天选局,偷摸溜了出去,进到厕所,发现商店中静静躺着一张伊泽瑞尔,而后又在接下来的选秀中拿到铲子和腰带,你激动的合成了心之钢转,在你放上伊泽瑞尔后,发现你现在没有凯隐,因此你将一张布里茨放了上去,给它一张心之钢转,当当当!七心之钢!心之钢转就是......
  • 如何将 Python 项目打包成 exe,另带卸载功能!
    前言虽然我是做web的,但是对Python的众多开源项目一直都很关注。像之前的stablediffusion的AI绘画,和so-vits-svc音色替换等源码的部署文档都很完善了。尽管如此,对于刚入门的和本地环境搭建各种踩坑的同学,又急于一试就显得不太友好了。针对这一现象,网上早有了各种大佬做......
  • 设计模式—模板模式
    介绍代码游戏模板类定义一个游戏模板虚类Game,抽象并规范好游戏的进行流程publicabstractclassGame{abstractvoidinit();abstractvoidstartPlay();abstractvoidendPlay();//模板publicfinalvoidplay(){//初始化......
  • 手把手教你用python做一个年会抽奖系统
    引言马上就要举行年会抽奖了,我们都不知道是否有人能够中奖。我觉得无聊的时候可以尝试自己写一个抽奖系统,主要是为了娱乐。现在人工智能这么方便,写一个简单的代码不是一件困难的事情。今天我想和大家一起构建一个简易的抽奖系统,这样也能够巩固一下我自己对Python语法和框架的理解......
  • 设计模式—策略模式
    介绍在策略模式(StrategyPattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代......
  • python xattr库
    因:ceph有一条设置文件/目录配额的命令ceph.quota.max_bytes,想在Python代码中调用它,最直接的方法是使用popen/subprocess等库直接执行这条命令,但如果频繁调用担心会影响系统性能,查阅资料发现xattr库也可以实现且更加方便。开始吧首先需要安装xattr库pip3installxattr......
  • 12.19---python
    seek()方法语法如下:file.seek(offset[,whece])offset--开始的偏移量,也就是代表需要移动偏移的字节数,如果是负数表示从倒数第几位开始。whence:可选,默认值为0。给offset定义一个参数,表示要从那个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾......
  • 【Python微信机器人】第六篇:优化使用方式,可pip安装
    优化内容这篇不聊技术点,说一下优化后的Python机器人代码怎么使用,优化内容如下:将hook库独立成一个库,发布到pypi,可使用pip安装将微信相关的代码发布成另一个库,也可以pip安装git仓库统一,以后都在这个仓库更新,不再一篇文章一个仓库开始建群,根据群里反馈增加功能和修复bug使用......
  • linux中部署python项目
    参考这篇博客:https://blog.csdn.net/smilehappiness/article/details/1173379431.首先查看python的版本:python-V2.安装python:3.安装虚拟环境报错1: 解决办法:export CURL_CA_BUNDLE="/etc/pki/tls/certs/ca-bundle.crt"https://3ms.huawei.com/km/blogs/details/14442367htt......