设计模式——建造者模式(生成器模式)总结

news2025/4/16 6:53:27

当我们需要创建一个非常复杂的对象时,可以使用建造者模式,分步骤建造一个对象,最后将完整的对象返回给客户端。

比如,我们要生成一个房子对象,建造一个房子,需要打地基、盖围墙、盖地板、安装门、安装窗户,有的房子还要盖车库,有的房子还要盖花园,有的房子要盖游泳池,有的。。。总之,房子是个很复杂的对象,涉及上百种不同的配置。

如果我们直接用房子类来创建房子对象,则需要输入几百参数:地基参数、围墙参数、地板参数、门参数、窗户参数,车库参数、花园参数、泳池参数。。等等几百个参数。

参数众多是一个问题,还有一个问题是,可能绝大多数房子用其中一小部分参数就可以了,其他大部分参数则都是压根用不到的,比如有的房子它不要车库,不要花园,不要泳池,那我们如果直接使用房子类来创建房子对象,这么多参数不就是多此一举了吗?

此时,则适宜使用建造者模式。建造者模式中的关键角色是建造者,建造者就像我们现实世界中的工程队一样,它拥有打地基、盖围墙、盖地板等等所有盖房子的众多方法,而我们用户端,则根据我们客户的需要,仅调用我们需要的方法即可。

更进一步,我们可以引入一个建造者主管的角色,建造者主管能够记住我们客户经常调用的建造者技能,比如建造市面上常用的三室一厅的房子,以前我们客户每需要一个三室一厅的房子,需要告诉建造者应该先打地基,再盖地板,再。。。,现在有了建造者主管这个角色,我们客户只需要告诉建造者主管,我需要一个三室一厅的房子就可以了,主管会安排建造者如果使用建造的方法。

建造者模式基本的逻辑就这么多了,这里需要补充两个容易遗漏的点:1,建造者需要有交付房子的方法,这样才能给客户端返回客户需要的房子。2,建造者需要有reset的方法,这样下一个客户调用建造者盖房子时,建造者就会从头开始盖,而不是在上一个房子的基础上继续盖。

实现代码如下:

"""
我们来思考如何创建一个 房屋House对象。 建造一栋简单的房屋, 首先你需要建造四面墙和地板, 安装房门和一套窗户, 然后再建造一个屋顶。
但是如果你想要一栋更宽敞更明亮的房屋, 还要有院子和其他设施 (例如暖气、 排水和供电设备), 那又该怎么办呢?
"""
from abc import ABC,abstractmethod

# 建造者父类
class Builder(ABC):
    def __init__(self):
        self.house = House()
    @abstractmethod
    def build_base(self,number):
        pass
    @abstractmethod
    def build_wall(self,number):
        pass
    @abstractmethod
    def build_roof(self,number):
        pass
    @abstractmethod
    def build_door(self,number):
        pass
    @abstractmethod
    def build_window(self,number):
        pass
    @abstractmethod
    def build_garage(self,number):
        pass
    @abstractmethod
    def build_swimming_pool(self,number):
        pass
    @abstractmethod
    def build_garden(self,number):
        pass
    @abstractmethod
    def deliver_house(self):
        pass

    def 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):
        pass

    def build_wall(self, number):
        pass

    def build_roof(self, number):
        pass

    def build_door(self, number):
        pass

    def build_window(self, number):
        pass

    def build_garage(self, number):
        pass

    def build_swimming_pool(self, number):
        pass

    def build_garden(self, number):
        pass

    def deliver_house(self):
        pass


# 这是一个建造高档房子的建造者
class UpscaleBuilder(Builder):
    def __init__(self):
        super().__init__()

    def build_base(self, number):
        pass

    def build_wall(self, number):
        pass

    def build_roof(self, number):
        pass

    def build_door(self, number):
        pass

    def build_window(self, number):
        pass

    def build_garage(self, number):
        pass

    def build_swimming_pool(self, number):
        pass

    def build_garden(self, number):
        pass

    def 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 = builder

    def 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())

以下是运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334882.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用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 &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 2、思路 参考官方题解&#xff0c;基本思路…

14-大模型微调和训练之-Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析(二分类))

1. datasets 库核心方法 1.1. 列出数据集 使用 datasets 库&#xff0c;你可以轻松列出所有 Hugging Face 平台上的数据集&#xff1a; from datasets import list_datasets # 列出所有数据集 all_datasets list_datasets() print(all_datasets)1.2. 加载数据集 你可以通过…

论文阅读笔记——Reactive Diffusion Policy

RDP 论文 通过 AR 提供实时触觉/力反馈&#xff1b;慢速扩散策略&#xff0c;用于预测低频潜在空间中的高层动作分块&#xff1b;快速非对称分词器实现闭环反馈控制。 ACT、 π 0 \pi_0 π0​ 采取了动作分块&#xff0c;在动作分块执行期间处于开环状态&#xff0c;无法及时响…

ISIS协议(动态路由协议)

ISIS基础 基本概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是ISO &#xff08;International Organization for Standardization&#xff0c;国际标准化组织&#xff09;为它的CLNP&#xff08;ConnectionL…

UniApp 实现兼容 H5 和小程序的拖拽排序组件

如何使用 UniApp 实现一个兼容 H5 和小程序的 九宫格拖拽排序组件&#xff0c;实现思路和关键步骤。 一、完整效果图示例 H5端 小程序端 git地址 二、实现目标 支持拖动菜单项改变顺序拖拽过程实时预览移动位置拖拽松开后自动吸附回网格兼容 H5 和小程序平台 三、功能…

【网络协议】WebSocket讲解

目录 webSocket简介 连接原理解析: 客户端API 服务端API&#xff08;java&#xff09; 实战案例 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;编写服务端逻辑 &#xff08;3&#xff09;注册配置类 &#xff08;4&#xff09;前端连接 WebSocket 示例…

啥是Spring,有什么用,既然收费,如何免费创建SpringBoot项目,依赖下载不下来的解决方法,解决99%问题!

一、啥是Spring&#xff0c;为啥选择它 我们平常说的Spring指的是Spring全家桶&#xff0c;我们为什么要选择Spring&#xff0c;看看官方的话&#xff1a; 意思就是&#xff1a;用这个东西&#xff0c;又快又好又安全&#xff0c;反正就是好处全占了&#xff0c;所以我们选择它…

一天时间,我用AI(deepseek)做了一个配色网站

前言 最近在开发颜色搭配主题的相关H5和小程序&#xff0c;想到需要补充一个web网站&#xff0c;因此有了这篇文章。 一、确定需求 向AI要答案之前&#xff0c;一定要清楚自己想要做什么。如果你没有100%了解自己的需求&#xff0c;可以先让AI帮你理清逻辑和思路&#xff0c;…

Spring - 13 ( 11000 字 Spring 入门级教程 )

一&#xff1a; Spring AOP 备注&#xff1a;之前学习 Spring 学到 AOP 就去梳理之前学习的知识点了&#xff0c;后面因为各种原因导致 Spring AOP 的博客一直搁置。。。。。。下面开始正式的讲解。 学习完 Spring 的统一功能后&#xff0c;我们就进入了 Spring AOP 的学习。…

Spring Cloud Alibaba微服务治理实战:Nacos+Sentinel深度解析

一、引言 在微服务架构中&#xff0c;服务发现、配置管理、流量控制是保障系统稳定性的核心问题。Spring Cloud Netflix 生态曾主导微服务解决方案&#xff0c;但其部分组件&#xff08;如 Eureka、Hystrix&#xff09;已进入维护模式。 Spring Cloud Alibaba 凭借 高性能、轻…

红宝书第三十六讲:持续集成(CI)配置入门指南

红宝书第三十六讲&#xff1a;持续集成&#xff08;CI&#xff09;配置入门指南 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、什么是持续集成&#xff1f; 持续集成&#xff08;CI&#xff09;就像咖啡厅的…

Java—HTML:3D形变

今天我要介绍的是在Java HTML中CSS的相关知识点内容之一&#xff1a;3D形变&#xff08;3D变换&#xff09;。该内容包含透视&#xff08;属性&#xff1a;perspective&#xff09;&#xff0c;3D变换&#xff0c;3D变换函数以及案例演示&#xff0c; 接下来我将逐一介绍&…

什么是音频预加重与去加重,预加重与去加重的原理是什么,在什么条件下会使用预加重与去加重?

音频预加重与去加重是音频处理中的两个重要概念&#xff0c;以下是对其原理及应用条件的详细介绍&#xff1a; 1、音频预加重与去加重的定义 预加重&#xff1a;在音频信号的发送端&#xff0c;对音频信号的高频部分进行提升&#xff0c;增加高频信号的幅度&#xff0c;使其在…

免费下载 | 2025清华五道口:“十五五”金融规划研究白皮书

《2025清华五道口&#xff1a;“十五五”金融规划研究白皮书》的核心内容主要包括以下几个方面&#xff1a; 一、五年金融规划的重要功能与作用 凝聚共识&#xff1a;五年金融规划是国家金融发展的前瞻性谋划和战略性安排&#xff0c;通过广泛听取社会各界意见&#xff0c;凝…

微信小程序实战案例 - 餐馆点餐系统 阶段 4 - 订单列表 状态

✅ 阶段 4 – 订单列表 & 状态 目标 展示用户「我的订单」列表支持状态筛选&#xff08;全部 / 待处理 / 已完成&#xff09;支持分页加载和实时刷新使用原生组件编写 ✅ 1. 页面结构&#xff1a;文件结构 pages/orders/├─ index.json├─ index.wxml├─ index.js└─…