设计模式——建造者模式(生成器模式)总结
当我们需要创建一个非常复杂的对象时,可以使用建造者模式,分步骤建造一个对象,最后将完整的对象返回给客户端。
比如,我们要生成一个房子对象,建造一个房子,需要打地基、盖围墙、盖地板、安装门、安装窗户,有的房子还要盖车库,有的房子还要盖花园,有的房子要盖游泳池,有的。。。总之,房子是个很复杂的对象,涉及上百种不同的配置。
如果我们直接用房子类来创建房子对象,则需要输入几百参数:地基参数、围墙参数、地板参数、门参数、窗户参数,车库参数、花园参数、泳池参数。。等等几百个参数。
参数众多是一个问题,还有一个问题是,可能绝大多数房子用其中一小部分参数就可以了,其他大部分参数则都是压根用不到的,比如有的房子它不要车库,不要花园,不要泳池,那我们如果直接使用房子类来创建房子对象,这么多参数不就是多此一举了吗?
此时,则适宜使用建造者模式。建造者模式中的关键角色是建造者,建造者就像我们现实世界中的工程队一样,它拥有打地基、盖围墙、盖地板等等所有盖房子的众多方法,而我们用户端,则根据我们客户的需要,仅调用我们需要的方法即可。
更进一步,我们可以引入一个建造者主管的角色,建造者主管能够记住我们客户经常调用的建造者技能,比如建造市面上常用的三室一厅的房子,以前我们客户每需要一个三室一厅的房子,需要告诉建造者应该先打地基,再盖地板,再。。。,现在有了建造者主管这个角色,我们客户只需要告诉建造者主管,我需要一个三室一厅的房子就可以了,主管会安排建造者如果使用建造的方法。
建造者模式基本的逻辑就这么多了,这里需要补充两个容易遗漏的点:1,建造者需要有交付房子的方法,这样才能给客户端返回客户需要的房子。2,建造者需要有reset的方法,这样下一个客户调用建造者盖房子时,建造者就会从头开始盖,而不是在上一个房子的基础上继续盖。
实现代码如下:
"""
我们来思考如何创建一个 房屋House对象。 建造一栋简单的房屋, 首先你需要建造四面墙和地板, 安装房门和一套窗户, 然后再建造一个屋顶。
但是如果你想要一栋更宽敞更明亮的房屋, 还要有院子和其他设施 (例如暖气、 排水和供电设备), 那又该怎么办呢?
"""
from abc import ABC,abstractmethod# 建造者父类
class Builder(ABC):def __init__(self):self.house = House()@abstractmethoddef build_base(self,number):pass@abstractmethoddef build_wall(self,number):pass@abstractmethoddef build_roof(self,number):pass@abstractmethoddef build_door(self,number):pass@abstractmethoddef build_window(self,number):pass@abstractmethoddef build_garage(self,number):pass@abstractmethoddef build_swimming_pool(self,number):pass@abstractmethoddef build_garden(self,number):pass@abstractmethoddef deliver_house(self):passdef reset(self):self.house.parts.clear()class House:def __init__(self):self.parts = []def add(self,facilities):self.parts.append(facilities)def show(self):return f'This house has {','.join(self.parts)}'# 这是一个建造廉价房子的建造者,他会使用廉价的材料盖房子
class CheapBuilder(Builder):def __init__(self):super().__init__()def build_base(self,number):self.house.add(f'{number} cheap bases')def build_wall(self,number):self.house.add(f'{number} cheap walls')def build_roof(self,number):self.house.add(f'{number} cheap roofs')def build_door(self,number):self.house.add(f'{number} cheap doors')def build_window(self,number):self.house.add(f'{number} cheap windows')def build_garage(self,number):self.house.add(f'{number} cheap garages')def build_swimming_pool(self,number):self.house.add(f'{number} cheap swimming pools')def build_garden(self,number):self.house.add(f'{number} cheap gardens')def deliver_house(self):return self.house.show()# 这是一个建造中等质量房子的建造者
class MiddleBuilder(Builder):def __init__(self):super().__init__()def build_base(self, number):passdef build_wall(self, number):passdef build_roof(self, number):passdef build_door(self, number):passdef build_window(self, number):passdef build_garage(self, number):passdef build_swimming_pool(self, number):passdef build_garden(self, number):passdef deliver_house(self):pass# 这是一个建造高档房子的建造者
class UpscaleBuilder(Builder):def __init__(self):super().__init__()def build_base(self, number):passdef build_wall(self, number):passdef build_roof(self, number):passdef build_door(self, number):passdef build_window(self, number):passdef build_garage(self, number):passdef build_swimming_pool(self, number):passdef build_garden(self, number):passdef deliver_house(self):pass# 这是建造者主管
class Director:# 这是主管记住的建造基本房子的方案def build_basic_house(self,builder):builder.build_base(1)builder.build_roof(1)builder.build_wall(4)builder.build_window(1)builder.build_door(1)# 这是主管记住的建造最流行的房子的方案def build_popular_house(self,builder):builder.build_base(1)builder.build_roof(1)builder.build_wall(4)builder.build_window(2)builder.build_door(1)builder.build_garage(1)class Client:def __init__(self,builder):self.director = Director()self.builder = builderdef buy_basic_house(self):self.director.build_basic_house(self.builder)def get_house(self):return self.builder.deliver_house()if __name__ == "__main__":client = Client(CheapBuilder())client.buy_basic_house()print(client.get_house())
以下是运行结果:

相关文章:
设计模式——建造者模式(生成器模式)总结
当我们需要创建一个非常复杂的对象时,可以使用建造者模式,分步骤建造一个对象,最后将完整的对象返回给客户端。 比如,我们要生成一个房子对象,建造一个房子,需要打地基、盖围墙、盖地板、安装门、安装窗户…...
Spring Boot(二十一):RedisTemplate的String和Hash类型操作
RedisTemplate和StringRedisTemplate的系列文章详见: Spring Boot(十七):集成和使用Redis Spring Boot(十八):RedisTemplate和StringRedisTemplate Spring Boot(十九)…...
使用Python爬虫的2大原因和6大常用库
爬虫其实就是请求http、解析网页、存储数据的过程,并非高深的技术,但凡是编程语言都能做,连Excel VBA都可以实现爬虫,但Python爬虫的使用频率最高、场景最广。 这可不仅仅是因为Python有众多爬虫和数据处理库,还有一个…...
Java 架构设计:从单体架构到微服务的转型之路
Java 架构设计:从单体架构到微服务的转型之路 在现代软件开发中,架构设计的选择对系统的可扩展性、可维护性和性能有着深远的影响。随着业务需求的日益复杂和用户规模的不断增长,传统的单体架构逐渐暴露出其局限性,而微服务架构作…...
C# 混淆代码工具--ConfuserEx功能与使用指南
目录 1 前言1.1 可能带来的问题 2 ConfuserEx2.1 简介2.2 功能特点2.3 基本使用方法2.4 集成到MSBuild2.5 深入设置2.5.1 保护机制2.5.1.1 ConfuserEx Protection 2.5.2 精细的代码保护主要特性1. decl-type(string)2.full-name(string)3. is-public()4. match(string)5. match…...
使用PyTorch实现目标检测边界框转换与可视化
一、引言 在目标检测任务中,边界框(Bounding Box)的坐标表示与转换是核心基础操作。本文将演示如何: 实现边界框的两种表示形式(角点坐标 vs 中心坐标)之间的转换 使用Matplotlib在图像上可视化边界框 验…...
nlp面试重点
深度学习基本原理:梯度下降公式,将损失函数越来越小,最终预测值和实际值误差比较小。 交叉熵:-p(x)logq(x),p(x)是one-hot形式。如果不使用softmax计算交叉熵,是不行的。损失函数可能会非常大,…...
欢乐力扣:反转链表二
文章目录 1、题目描述2、思路 1、题目描述 反转链表二。 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 2、思路 参考官方题解,基本思路…...
2025最新系统 Git 教程(七)(完结)
第4章 分布式Git 4.1 分布式 Git - 分布式工作流程 你现在拥有了一个远程 Git 版本库,能为所有开发者共享代码提供服务,在一个本地工作流程下,你也已经熟悉了基本 Git 命令。你现在可以学习如何利用 Git 提供的一些分布式工作流程了。 这一…...
14-大模型微调和训练之-Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析(二分类))
1. datasets 库核心方法 1.1. 列出数据集 使用 datasets 库,你可以轻松列出所有 Hugging Face 平台上的数据集: from datasets import list_datasets # 列出所有数据集 all_datasets list_datasets() print(all_datasets)1.2. 加载数据集 你可以通过…...
聊透多线程编程-线程基础-4.C# Thread 子线程执行完成后通知主线程执行特定动作
在多线程编程中,线程之间的同步和通信是一个常见的需求。例如,我们可能需要一个子线程完成某些任务后通知主线程,并由主线程执行特定的动作。本文将基于一个示例程序,详细讲解如何使用 AutoResetEvent 来实现这种场景。 示例代码…...
论文阅读笔记——Reactive Diffusion Policy
RDP 论文 通过 AR 提供实时触觉/力反馈;慢速扩散策略,用于预测低频潜在空间中的高层动作分块;快速非对称分词器实现闭环反馈控制。 ACT、 π 0 \pi_0 π0 采取了动作分块,在动作分块执行期间处于开环状态,无法及时响…...
ISIS协议(动态路由协议)
ISIS基础 基本概念 IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是ISO (International Organization for Standardization,国际标准化组织)为它的CLNP(ConnectionL…...
大数据(7.1)Kafka实时数据采集与分发的企业级实践:从架构设计到性能调优
目录 一、实时数据洪流下的技术突围1.1 行业需求演进曲线1.2 传统方案的技术瓶颈 二、Kafka实时架构设计精要2.1 生产者核心参数矩阵2.1.1 分区策略选择指南 2.2 消费者组智能负载均衡 三、实时数据管道实战案例3.1 电商大促实时看板3.2 工业物联网预测性维护 四、生产环境性能…...
UniApp 实现兼容 H5 和小程序的拖拽排序组件
如何使用 UniApp 实现一个兼容 H5 和小程序的 九宫格拖拽排序组件,实现思路和关键步骤。 一、完整效果图示例 H5端 小程序端 git地址 二、实现目标 支持拖动菜单项改变顺序拖拽过程实时预览移动位置拖拽松开后自动吸附回网格兼容 H5 和小程序平台 三、功能…...
C,C++,C#
C、C 和 C# 是三种不同的编程语言,虽然它们名称相似,但在设计目标、语法特性、运行环境和应用场景上有显著区别。以下是它们的核心区别: 1. 设计目标和历史 语言诞生时间设计目标特点C1972(贝尔实验室)面向过程&#…...
MySQL | 三大日志文件
Undo Log(回滚日志) 实现原理与分类 原理:Undo Log 记录的是数据修改前的旧值,通过这些旧值可以将数据恢复到修改之前的状态。它采用的是逻辑日志,即记录的是如何撤销操作,而不是物理数据的实际值。 分类…...
【网络协议】WebSocket讲解
目录 webSocket简介 连接原理解析: 客户端API 服务端API(java) 实战案例 (1)引入依赖 (2)编写服务端逻辑 (3)注册配置类 (4)前端连接 WebSocket 示例…...
啥是Spring,有什么用,既然收费,如何免费创建SpringBoot项目,依赖下载不下来的解决方法,解决99%问题!
一、啥是Spring,为啥选择它 我们平常说的Spring指的是Spring全家桶,我们为什么要选择Spring,看看官方的话: 意思就是:用这个东西,又快又好又安全,反正就是好处全占了,所以我们选择它…...
一天时间,我用AI(deepseek)做了一个配色网站
前言 最近在开发颜色搭配主题的相关H5和小程序,想到需要补充一个web网站,因此有了这篇文章。 一、确定需求 向AI要答案之前,一定要清楚自己想要做什么。如果你没有100%了解自己的需求,可以先让AI帮你理清逻辑和思路,…...
Day14:关于MySQL的索引——创、查、删
前言:先创建一个练习的数据库和数据 1.创建数据库并创建数据表的基本结构 -- 创建练习数据库 CREATE DATABASE index_practice; USE index_practice;-- 创建基础表(包含CREATE TABLE时创建索引) CREATE TABLE products (id INT PRIMARY KEY…...
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二)
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二) 7. 实现条件WGAN-GP # 训练条件WGAN-GP def train_conditional_wgan_gp():# 用于记录损失d_losses []g_losses []# 用于记录生成样本的多样性(通过类别分…...
Spring - 13 ( 11000 字 Spring 入门级教程 )
一: Spring AOP 备注:之前学习 Spring 学到 AOP 就去梳理之前学习的知识点了,后面因为各种原因导致 Spring AOP 的博客一直搁置。。。。。。下面开始正式的讲解。 学习完 Spring 的统一功能后,我们就进入了 Spring AOP 的学习。…...
Spring Cloud Alibaba微服务治理实战:Nacos+Sentinel深度解析
一、引言 在微服务架构中,服务发现、配置管理、流量控制是保障系统稳定性的核心问题。Spring Cloud Netflix 生态曾主导微服务解决方案,但其部分组件(如 Eureka、Hystrix)已进入维护模式。 Spring Cloud Alibaba 凭借 高性能、轻…...
设计模式之迭代器模式:遍历的艺术与实现
引言 迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种顺序访问聚合对象中各个元素的方法,而又不暴露其底层实现。迭代器模式将遍历逻辑与聚合对象解耦,使得我们可以用统一的方式处理不同的集合结构。…...
红宝书第三十六讲:持续集成(CI)配置入门指南
红宝书第三十六讲:持续集成(CI)配置入门指南 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、什么是持续集成? 持续集成(CI)就像咖啡厅的…...
Java—HTML:3D形变
今天我要介绍的是在Java HTML中CSS的相关知识点内容之一:3D形变(3D变换)。该内容包含透视(属性:perspective),3D变换,3D变换函数以及案例演示, 接下来我将逐一介绍&…...
什么是音频预加重与去加重,预加重与去加重的原理是什么,在什么条件下会使用预加重与去加重?
音频预加重与去加重是音频处理中的两个重要概念,以下是对其原理及应用条件的详细介绍: 1、音频预加重与去加重的定义 预加重:在音频信号的发送端,对音频信号的高频部分进行提升,增加高频信号的幅度,使其在…...
免费下载 | 2025清华五道口:“十五五”金融规划研究白皮书
《2025清华五道口:“十五五”金融规划研究白皮书》的核心内容主要包括以下几个方面: 一、五年金融规划的重要功能与作用 凝聚共识:五年金融规划是国家金融发展的前瞻性谋划和战略性安排,通过广泛听取社会各界意见,凝…...
微信小程序实战案例 - 餐馆点餐系统 阶段 4 - 订单列表 状态
✅ 阶段 4 – 订单列表 & 状态 目标 展示用户「我的订单」列表支持状态筛选(全部 / 待处理 / 已完成)支持分页加载和实时刷新使用原生组件编写 ✅ 1. 页面结构:文件结构 pages/orders/├─ index.json├─ index.wxml├─ index.js└─…...
