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

Python 如何实践 Builder(生成器) 对象创建型设计模式?

开始之前,我们先介绍一下该模型的基本信息。

生成器(Builder)设计模式是一种创建型设计模式,它用于创建复杂对象,将对象的构建过程与表示分离。这种分离可以让我们创建不同类型或配置的对象,同时避免构造函数参数列表的爆炸性增长。

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用性

在以下情况下使用 Builder 模式:

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

在 Python 中,我们可以使用类和方法来实现生成器模式。以下是一个简单的示例,演示如何在 Python 中实践生成器设计模式:

# 创建产品类
class Product:def __init__(self):self.part1 = Noneself.part2 = Nonedef __str__(self):return f"Part1: {self.part1}, Part2: {self.part2}"# 创建生成器接口
class Builder:def build_part1(self):passdef build_part2(self):passdef get_product(self):pass# 具体生成器实现
class ConcreteBuilder(Builder):def __init__(self):self.product = Product()def build_part1(self):self.product.part1 = "Part 1 built"def build_part2(self):self.product.part2 = "Part 2 built"def get_product(self):return self.product# 创建导演类(可选)
class Director:def construct(self, builder):builder.build_part1()builder.build_part2()# 客户端代码
if __name__ == "__main__":builder = ConcreteBuilder()  # 实例化具体生成器director = Director()  # 创建导演对象(可选)# 构建产品director.construct(builder)  # 如果没有导演,也可以直接调用生成器的方法构建产品product = builder.get_product()  # 获取构建好的产品print(product)

在这个示例中,我们首先定义了产品类 Product,它有两个部分(part1 和 part2)。然后,我们创建了生成器接口 Builder,其中定义了创建产品的方法。接着,我们实现了具体的生成器类 ConcreteBuilder,它负责实际构建产品的各个部分。

最后,我们可以使用导演类(可选)来协调生成器的构建步骤,或者直接在客户端代码中使用生成器构建产品。生成器模式允许你以灵活的方式构建不同配置的产品,同时保持构建过程的分离。这对于构建复杂对象或者具有多个可选部分的对象非常有用。

📢 「导演类」通常就是指实现了导演模式的类,通常被命名为 Director。导演类的主要职责是协调生成器的构建步骤,指导生成器如何构建复杂对象,以确保对象的正确组装。


当理解生成器设计模式时,一个经典的示例是创建一个文档对象,例如 HTML 文档,其中包含多个部分,例如标题、段落、列表等。
以下是一个更具体的示例,演示如何使用生成器模式创建一个简单的 HTML 文档:

# 创建产品类
class HTMLDocument:def __init__(self):self.content = ""def add_content(self, content):self.content += contentdef __str__(self):return f"<html>\n{self.content}\n</html>"# 创建生成器接口
class DocumentBuilder:def build_title(self, title):passdef build_paragraph(self, text):passdef build_list(self, items):passdef get_document(self):pass# 具体生成器实现
class HTMLDocumentBuilder(DocumentBuilder):def __init__(self):self.document = HTMLDocument()def build_title(self, title):self.document.add_content(f"<head><title>{title}</title></head>")def build_paragraph(self, text):self.document.add_content(f"<p>{text}</p>")def build_list(self, items):item_list = "\n".join([f"<li>{item}</li>" for item in items])self.document.add_content(f"<ul>\n{item_list}\n</ul>")def get_document(self):return self.document# 客户端代码
if __name__ == "__main__":builder = HTMLDocumentBuilder()builder.build_title("Sample HTML Document")builder.build_paragraph("This is a sample HTML document.")builder.build_list(["Item 1", "Item 2", "Item 3"])document = builder.get_document()print(document)

在这个示例中,我们定义了产品类 HTMLDocument,具有一个字符串内容字段。生成器接口 DocumentBuilder 声明了创建 HTML 文档的方法。然后,我们实现了具体的生成器类 HTMLDocumentBuilder,它负责构建 HTML 文档的各个部分。

客户端代码使用生成器来构建 HTML 文档。首先,它创建了一个生成器对象,然后使用生成器的方法逐步构建标题、段落和列表。最后,通过调用 get_document 方法获取构建好的 HTML 文档对象并打印出来。

这个示例演示了如何使用生成器模式创建一个复杂的对象,而不必担心对象的内部构建细节,同时也允许你以不同的方式构建不同类型的 HTML 文档。这有助于将构建过程和产品的表示分离开来。


好了,这次就介绍到这里吧,喜欢的小伙伴们别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍎

相关文章:

Python 如何实践 Builder(生成器) 对象创建型设计模式?

开始之前&#xff0c;我们先介绍一下该模型的基本信息。 生成器&#xff08;Builder&#xff09;设计模式是一种创建型设计模式&#xff0c;它用于创建复杂对象&#xff0c;将对象的构建过程与表示分离。这种分离可以让我们创建不同类型或配置的对象&#xff0c;同时避免构造函…...

【Qt绘制小猪】以建造者模式绘制小猪

效果 学以致用&#xff0c;使用设计模式之建造者模式绘制小猪。 代码 接口&#xff1a;申明绘制的步骤 PigBuilder.h #ifndef PIGBUILDER_H #define PIGBUILDER_H#include <QObject> #include <QPainter>class PigBuilder : public QObject {Q_OBJECT public:ex…...

开发中常用的SQL语句

开发中常用的SQL语句 1.update更新时不能引用本身表2.备份MySQL3.函数的使用1. case,when的使用2. IF3.其它4.拼接5. 处理时间 4.导出表结构注释等 1.update更新时不能引用本身表 UPDATE student SET valid_flag 0 WHERE id IN (SELECT idFROM (SELECT su.idFROM student su …...

Unreal UnLua + Lua Protobuf

Unreal UnLua Lua Protobuf https://protobuf.dev/ protobuf wire format&#xff1a;pb 编译到底层的数据协议 https://github.com/starwing/lua-protobuf/blob/master/README.zh.md buffer 处理 lua string 可以当 buffer 用&#xff0c;# len 不会遇到 0 截断&#xf…...

java 类和对象 (图文搭配,万字详解!!)

关于java类和对象&#xff0c;我们要掌握几个重点&#xff01; 1.类的定义方式以及对象的实例化 2.类中的成员变量和成员方法的使用 3.对象的整个初始化过程 4.封装特性 5.代码块 目录 一、面向对象的初步认识 1.1 什么是面向对象 1.2 面向对象与面向过程 1.2.1传统洗…...

pytorch DistributedDataParallel 分布式训练踩坑记录

目录 一、几个比较常见的概念&#xff1a;二、踩坑记录2.1 dist.init_process_group初始化2.2 spawn启动&#xff08;rank怎么来的&#xff09;2.3 loss backward2.4 model cuda设置2.5 数据加载 一、几个比较常见的概念&#xff1a; rank: 多机多卡时代表某一台机器&#xff…...

Stable Diffusion webui 源码调试(三)

Stable Diffusion webui 源码调试&#xff08;三&#xff09; 个人模型主页&#xff1a;LibLibai stable-diffusion-webui 版本&#xff1a;v1.4.1 内容更新随机&#xff0c;看心情调试代码~ shared 变量 shared变量&#xff0c;简直是一锅大杂烩&#xff0c;shared变量存放…...

工作学习记录

1、Spring的Lifecycle和SmartLifecycle Spring的Lifecycle和SmartLifecycle&#xff0c;可以没用过&#xff0c;但不能不知道&#xff01;-CSDN博客 2、Shiro安全框架提供了认证、授权、企业会话管理、加密、缓存管理相关的功能&#xff0c;使用Shiro可以非常方便的完成项目的…...

邻接矩阵储存图实现深度优先遍历(C++)

目录 基本要求&#xff1a; 图的结构体&#xff1a; 图的构造&#xff1a; 图的深度优先&#xff08;DFS&#xff09;&#xff1a; 图的打印输出&#xff1a; 完整代码&#xff1a; 测试数据&#xff1a; 运行结果&#xff1a; 通过给出的图的顶点和边的信息&#xff0c…...

hdlbits系列verilog解答(100位加法器)-42

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 通过实例化 100 个完整加法器来创建一个 100 位二进制纹波进位加法器。加法器将两个 100 位数字和一个进位相加,以产生一个 100 位的总和并执行。为了鼓励您实际实例化全加法器,还要在纹波进位加法器中输出每…...

学者观察 | 数字经济中长期发展中的区块链影响力——清华大学柴跃廷

导语 区块链是一种全新的分布式基础架构与计算范式&#xff0c;既能利用非对称加密和冗余分布存储实现信息不可篡改&#xff0c;又可以利用链式数据结构实现数据信息可溯源。当前&#xff0c;区块链技术已成为全球数据交易、金融结算、国际贸易、政务民生等领域的信息基础设施…...

python-flask笔记

服务器图形工具&#xff1a;FinalShellpython虚拟环境用anaconda 标题技术架构和依赖 python3.8 环境 Flask 后端框架 flask-marshmallow webargs 处理参数接收 postgresql 数据库 psycopg2-binary postgresql操作库 Flask-SQLAlchemy orm操作库 flask-admin 超管管理后台 …...

tensor和ndarray的相互转换,同时需要注意cuda和cpu的迁移

从tensor到ndarray&#xff1a;.detach() 方法用于创建一个新的张量&#xff0c;新张量与原始张量共享数据内存&#xff0c;但是不会被计算图追踪。这意味着在新张量上的操作不会影响到原始张量&#xff0c;同时也可以避免梯度传播&#xff0c;适合于提取中间结果。 # 当tenso…...

《Swin Transformer: Hierarchical Vision Transformer using Shifted Windows》阅读笔记

论文标题 《Swin Transformer: Hierarchical Vision Transformer using Shifted Windows》 Swin 这个词貌似来自后面的 Shifted WindowsShifted Windows&#xff1a;移动窗口Hierarchical&#xff1a;分层 作者 微软亚洲研究院出品 初读 摘要 提出 Swin Transformer 可以…...

Flink 基础 -- 应用开发(Table API SQL) 概念和通用API

1、概述 Apache Flink提供了两个关系API——Table API和SQL——用于统一的流和批处理。Table API是一个用于Java、Scala和Python的语言集成查询API&#xff0c;它允许以非常直观的方式组合来自关系操作符(如选择、过滤和连接)的查询。Flink的SQL支持基于Apache Calcite&#x…...

Flink之Java Table API的使用

Java Table API的使用 使用Java Table API开发添加依赖创建表环境创建表查询表输出表使用示例 表和流的转换流DataStream转换成表Table表Table转换成流DataStream示例数据类型 自定义函数UDF标量函数表函数聚合函数表聚合函数 API方法汇总基本方法列操作聚合操作Joins合并操作排…...

【Unity细节】Unity中如何让组件失活而不是物体失活

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…...

[设计模式] 建造者模式

一、引言 起因是学习okhttp过程中遇到的这段代码 Request request original.newBuilder().url(original.url()).header("Authorization", "Bearer " BearerTokenUtils.getToken(configuration.getApiKey(), configuration.getApiSecret())).header(&quo…...

在DDD领域驱动下的微服务数据库的MVC设计思路(高度可行性)

在DDD领域驱动下的微服务架构中使用MVC设计思路来设计数据库是可行的&#xff0c;因为MVC是一种经典的软件架构模式&#xff0c;可以将应用程序分为三个主要部分&#xff1a;模型、视图和控制器。在微服务架构中&#xff0c;每个微服务可以看作是一个模块&#xff0c;可以使用M…...

Leetcode2834. 找出美丽数组的最小和

Every day a Leetcode 题目来源&#xff1a;2834. 找出美丽数组的最小和 解法1&#xff1a;贪心 从最小正整数 1 开始枚举&#xff0c;设当前数为 num&#xff0c;如果 nums 里没有 target - num&#xff0c;就说明可以添加 num&#xff0c;依次填满直到有 n 个数即可。 用…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...