设计模式Python版 原型模式

文章目录


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、原型模式

原型模式(Prototype Pattern)

  • 定义:使用原型实例指定创建对象的种类,并且通过克隆这些原型创建新的对象。
  • 解决问题:如何通过克隆来得到一个一模一样的对象?(通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址。)
  • 使用场景:
    • 创建新对象成本较大
    • 系统要保存对象的状态
    • 在运行时动态地创建和定制对象
  • 组成:
    • 原型接口(Prototype):声明克隆自身的接口
    • 具体原型(ConcretePrototype):实现原型接口,提供克隆自身的操作。
    • 客户端(Client):让一个原型克隆自身,从而创建一个新的对象。
  • 优点:
    • 当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率
    • 可以使用深克隆的方式保存对象的状态。使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用,例如恢复到某一历史状态,可辅助实现撤销操作
  • 缺点:
    • 注意深克隆与浅克隆的区别和使用场景

二、原型模式示例

使用原型模式快速创建工作周报

python 复制代码
import copy

class Prototype:
    """原型接口"""

    def clone(self):
        # 这里用深拷贝,这意味着对象及其所有引用的对象都将被复制
        # 若不希望复制对象内部的引用类型,copy.copy()来执行浅拷贝
        return copy.deepcopy(self)


class WeeklyLog(Prototype):
    """具体原型"""

    def __init__(self, name=None, date=None, content=None):
        self.name = name
        self.date = date
        self.content = content

客户端代码

python 复制代码
def display_log(log: WeeklyLog):
    print("###周报###")
    print(f"姓名:{log.name}")
    print(f"周次:{log.date}")
    print(f"内容:{log.content}")
    print("#" * 10, "\n")


log_lastweek = WeeklyLog("张三", "第12周", "这周工作很忙,每天加班!")
log_thisweek = log_lastweek.clone()
log_thisweek.date = "第13周"
display_log(log_lastweek)
display_log(log_thisweek)
print(log_lastweek is log_thisweek)  # 输出 False,表示是不同的对象

输出结果

sh 复制代码
###周报###
姓名:张三
周次:第12周
内容:这周工作很忙,每天加班!
##########

###周报###
姓名:张三
周次:第13周
内容:这周工作很忙,每天加班!
##########

False

三、原型管理器

  • 原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂
  • 原型管理器采用单例模式,能节省系统资源,也能更好地管理。定义一个集合存储原型对象,需要某个原型对象的一个克隆,调用相应对象的克隆方法来获得。
python 复制代码
import copy

"""原型接口"""

class OfficialDocument:
    def clone(self):
        return copy.deepcopy(self)

    def display(self):
        raise NotImplementedError


"""具体原型"""

class FAR(OfficialDocument):
    def display(self):
        print("《可行性分析报告》")


class SRS(OfficialDocument):
    def display(self):
        print("《软件需求规格说明书》")


"""原型管理器(使用模块单例模式)"""

class PrototypeManager:
    def __init__(self):
        self.official_docs: dict[str, OfficialDocument] = {}
        self.add_official_docs()

    def add_official_docs(self):
        self.official_docs["far"] = FAR()
        self.official_docs["srs"] = SRS()

    def get_official_doc(self, key: str) -> OfficialDocument:
        official_doc = self.official_docs.get(key, None)
        if official_doc:
            return official_doc.clone()


prototype_manager = PrototypeManager()
  • 客户端代码
python 复制代码
from prototypes import prototype_manager

doc1 = prototype_manager.get_official_doc("far")
doc2 = prototype_manager.get_official_doc("far")
doc1.display()
doc2.display()
print(doc1 is doc2)

doc3 = prototype_manager.get_official_doc("srs")
doc4 = prototype_manager.get_official_doc("srs")
doc3.display()
doc4.display()
print(doc3 is doc4)
  • 输出结果
sh 复制代码
《可行性分析报告》
《可行性分析报告》    
False
《软件需求规格说明书》
《软件需求规格说明书》
False

您正在阅读的是《设计模式Python版》专栏!关注不迷路~

相关推荐
chao_7894 分钟前
二分查找篇——寻找旋转排序数组中的最小值【LeetCode】
python·线性代数·算法·leetcode·矩阵
金玉满堂@bj21 分钟前
PyCharm 中 Python 解释器的添加选项及作用
ide·python·pycharm
程序员三藏26 分钟前
如何使用Pytest进行测试?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
随心点儿1 小时前
使用python 将多个docx文件合并为一个word
开发语言·python·多个word合并为一个
不学无术の码农1 小时前
《Effective Python》第十三章 测试与调试——使用 Mock 测试具有复杂依赖的代码
开发语言·python
sleepybear11131 小时前
在Ubuntu上从零开始编译并运行Home Assistant源码并集成HACS与小米开源的Ha Xiaomi Home
python·智能家居·小米·home assistant·米家·ha xiaomi home
纪伊路上盛名在1 小时前
(鱼书)深度学习入门1:python入门
人工智能·python·深度学习
夏末蝉未鸣012 小时前
python transformers笔记(TrainingArguments类)
python·自然语言处理·transformer
德育处主任Pro2 小时前
「py数据分析」04如何将 Python 爬取的数据保存为 CSV 文件
数据库·python·数据分析
智想天开2 小时前
31.设计模式的反模式与常见误区
设计模式