漫谈设计模式 [5]:建造者模式

news2024/9/17 7:19:44

引导性开场

菜鸟:老鸟,我最近在写一个项目,发现很多对象初始化的代码特别复杂,感觉乱糟糟的。有没有什么好的方法能帮我简化这些代码?

老鸟:嗯,你提到的这个问题其实很常见。你有没有听说过设计模式?

菜鸟:听说过,但一直没深入研究。设计模式真的能解决这个问题吗?

老鸟:当然可以!今天我们就来聊聊其中的一个:建造者模式(Builder Pattern)

渐进式介绍概念

老鸟:你可以把建造者模式想象成一个精心制作汉堡的过程。想象一下,你在一家汉堡店,你可以选择面包、肉饼、蔬菜、酱料等等。你可以按自己的喜好一步步定制一个汉堡。建造者模式就是把对象的创建过程分成多个步骤,逐步构建复杂对象。

菜鸟:哦,原来是这样!那建造者模式的核心思想是什么?

老鸟:核心思想就是将一个复杂对象的构建过程分离出来,使得构建过程可以一步步进行,并且不同的构建步骤可以有不同的实现方式。

Python代码示例,逐步展开

菜鸟:能给我看个具体的 Python 示例吗?

老鸟:当然可以。我们先从简单的例子开始。假设我们要创建一个 House 对象,包含 wallsdoorswindowsroof。我们先写一个基础实现。

class House:
    def __init__(self, walls=None, doors=None, windows=None, roof=None):
        self.walls = walls
        self.doors = doors
        self.windows = windows
        self.roof = roof

    def __str__(self):
        return f"House with {self.walls} walls, {self.doors} doors, {self.windows} windows, and {self.roof} roof."

# 使用基础实现创建对象
house = House(walls=4, doors=2, windows=8, roof="Gable")
print(house)

菜鸟:这个实现确实可以创建一个 House 对象,但感觉还是有些不够清晰,有点乱。

老鸟:你说得对。现在我们用建造者模式来改进它。

class HouseBuilder:
    def __init__(self):
        self.house = House()

    def build_walls(self, walls):
        self.house.walls = walls
        return self

    def build_doors(self, doors):
        self.house.doors = doors
        return self

    def build_windows(self, windows):
        self.house.windows = windows
        return self

    def build_roof(self, roof):
        self.house.roof = roof
        return self

    def get_house(self):
        return self.house

# 使用建造者模式创建对象
builder = HouseBuilder()
house = (builder.build_walls(4)
                .build_doors(2)
                .build_windows(8)
                .build_roof("Gable")
                .get_house())
print(house)

问题与反思

菜鸟:我明白了,这样代码更清晰了。但为什么不能直接用普通的方式实现呢?

老鸟:这是个好问题。普通的实现有几个问题:1. 初始化参数过多时,代码不易维护。 2. 如果需要创建不同类型的对象,代码会变得非常复杂。3. 难以扩展。建造者模式可以很好地解决这些问题。

菜鸟:听起来不错,但如何解决扩展的问题呢?

老鸟:假设我们现在要给房子添加一个花园和一个车库。用建造者模式来实现就很简单。

class HouseBuilder:
    # 省略之前的代码...

    def build_garden(self, garden):
        self.house.garden = garden
        return self

    def build_garage(self, garage):
        self.house.garage = garage
        return self

# 使用建造者模式创建带花园和车库的房子
builder = HouseBuilder()
house = (builder.build_walls(4)
                .build_doors(2)
                .build_windows(8)
                .build_roof("Gable")
                .build_garden("Beautiful Garden")
                .build_garage("Two-car Garage")
                .get_house())
print(house)

优势与适用场景

老鸟:建造者模式的优势很多,比如代码清晰、易于维护、便于扩展等。适用于以下场景:

  • 需要创建复杂对象时。
  • 对象创建过程需要分步骤进行。
  • 创建对象时需要灵活的构建过程。

常见误区与优化建议

菜鸟:有常见的误区和需要注意的地方吗?

老鸟:是的。常见误区包括:

  • 把建造者模式和工厂模式混淆。
  • 忽略建造者模式的分步骤特性。
    建议避免这些误区,确保每一步都清晰定义。

总结与延伸阅读

老鸟:今天我们讨论了建造者模式,从基础实现到逐步扩展,讲解了其优势和适用场景。你可以进一步阅读《设计模式:可复用面向对象软件的基础》这本书,了解更多设计模式。

菜鸟:谢谢老鸟!我觉得建造者模式真的很有用。我会继续学习其他设计模式。

老鸟:不客气!加油!

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

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

相关文章

AWQ量化(Activation-aware Weight Quantization)

论文: AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration 中文解读: 深入理解AWQ量化技术 - 知乎 (zhihu.com) 动机:端侧设备用LLM,为了减少显存占用量,所以要用INT4量化&am…

【Jupyter Notebook】汉化

1.打开:Anaconda Prompt 2.输入:"activate Zhui01"(注意:Zhui01是刚创建的环境名字) activate Zhui01 3.输入:"pip install jupyterlab-language-pack-zh-CN" pip install jupyterlab-language-pack-zh-CN 4.打开:Jupyter Notebook 5.点击&q…

Mysql高级篇(中)——七种常见的 join 查询图

注意: MySQL是不支持 FULL OUTER JOIN 这种语法的,因此要实现图中 6、7的查询结果,可以使用 UNION 关键字结合 LEFT JOIN、RIGHT JOIN 实现,UNION可以实现去重的效果; 参考如下代码: -- MySQL中 图标6 的实…

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class M…

MarginNote 4 激活码 - 苹果电脑(Mac)全能型的阅读工具

对广大求学者来说,如何科学有效地掌握知识,一定是大家不懈追求的方向。 众多求学者使用的,深度阅读学习工具 MarginNote,终于为 Mac 推出了官网 4.0 版。带来了众多创新的学习辅助工具。 MarginNote 4 功能简介 1、快速理清各版…

大数据新视界--大数据大厂之Java 与大数据携手:打造高效实时日志分析系统的奥秘

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

探索fastFM:Python中的高效推荐系统库

文章目录 🚀 探索fastFM:Python中的高效推荐系统库背景:为何选择fastFM?快照:fastFM是什么?安装指南:如何将fastFM加入你的项目?快速入门:五个基础函数的使用实战演练&am…

猫眼电影字体破解(图片转码方法)

问题 随便拿一篇电影做样例。我们发现猫眼的页面数据在预览窗口中全是小方框。在当我们拿到源码以后,数据全是加密后的。所以我们需要想办法破解加密,拿到数据。 破解过程 1.源码获取问题与破解 分析 在我们刚刚请求url的时候是可以得到数据的&#xff…

halcon 由离散点云生成3d模型(2步)

一,创建立方体的3d坐标,定义X,Y,Z坐标 dev_open_window (0, 0, 512, 512, black, WindowHandle) x:[0,0,1,1,0,0,1,1] y:[0,1,1,0,0,1,1,0] z:[0,0,0,0,2,2,2,2] 二,由3创建3d模型(在这里是将所有的点集合为一体) ge…

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds 总结 fd_set操作接口 timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充 获取新连接 注意点 -- 通信时的调用函数 添…

JavaScript使用高德API显示地图

前言 在JavaScript中,使用Leaflet库显示地图是一种常见的做法。Leaflet是一个开源的JavaScript库,用于在Web应用程序中创建互动地图。它非常轻量级,易于使用,并且提供了多种功能,使开发者能够轻松地将地图集成到他们的…

【Python报错已解决】 SyntaxError: positional argument follows keyword argument

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一:调整参数顺序2.2 步骤二…

银行贷款产品

1、对公贷款 1.1 一般贷款 按贷款期限可分为短期贷款和中长期贷款。短期贷款是指金融企业根据有关规定发放的,期限在1年(含1年)以下的各种贷款。中长期贷款是指金融企业发放的贷款期限在1年以上的各种贷款。 按提供方式不同可分为信用贷款、担保贷款等。信用贷款是指金融企…

springboot实战学习(1)(开发模式与环境)

目录 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 (3)前端 二、开发模式 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 Validation&#xf…

ubuntu上通过openvswitch卸载实现roce over vxlan

环境 操作系统: uname -a Linux 5.4.0-187-generic #207-Ubuntu SMP Mon Jun 10 08:16:10 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Mellanox网卡: ethtool -i ens6np0 driver: mlx5_core version: 23.10-2.1.3 firmware-version: 20.39.3004 (MT_0…

在Linux下查看HBA卡的速率和状态

平时在Linux下映射存储,都是映射哪台就给哪台插线,然后在存储端扫描WWPN,简单粗暴,没技术含量。当然,光交下也可以看。 1,查看当前卡的品牌,常用的卡有两种,Emulex和Qlogic。 lspc…

C语言 - 预处理详解(一)#预定义符号 ##define #undef

文章目录 前言 一、预定义符号 二、#define (一)、#define 定义的标识符 (二)、#define 定义的宏 (三)、#define 替换规则 (四)、# 和 ## 1、 # 的作用 2、## 的作用 (五)、带副作用的宏参数 (六)、宏和函数的对比 (七)、命名约定 三、#undef 总结 前言 路漫漫其修远兮&#…

C语言深度剖析--不定期更新的第五弹

const关键字 来看一段代码&#xff1a; #include <stdio.h> int main() {int a 10;a 20;printf("%d\n", a);return 0; }运行结果如下&#xff1a; 接下来我们在上面的代码做小小的修改&#xff1a; #include <stdio.h> int main() {const int a 1…

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口 int main(int argc, char *argv[]) {//…

IDA的安装和使用

IDA Pro&#xff08;简称 IDA&#xff0c;官网地址为 https://www.hex-rays.com/products/ida/&#xff09;是一个反编译器&#xff0c;同时具备调试器的功能。IDA Pro 的功能非常强大&#xff0c;几乎所有的逆向题目都需要用到它&#xff0c;因而也被称为「逆向神器」 IDA安装…