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

news/2024/11/12 20:20:19/

引导性开场

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

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

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

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

渐进式介绍概念

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

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

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

Python代码示例,逐步展开

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

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

python">class House:def __init__(self, walls=None, doors=None, windows=None, roof=None):self.walls = wallsself.doors = doorsself.windows = windowsself.roof = roofdef __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 对象,但感觉还是有些不够清晰,有点乱。

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

python">class HouseBuilder:def __init__(self):self.house = House()def build_walls(self, walls):self.house.walls = wallsreturn selfdef build_doors(self, doors):self.house.doors = doorsreturn selfdef build_windows(self, windows):self.house.windows = windowsreturn selfdef build_roof(self, roof):self.house.roof = roofreturn selfdef 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. 难以扩展。建造者模式可以很好地解决这些问题。

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

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

python">class HouseBuilder:# 省略之前的代码...def build_garden(self, garden):self.house.garden = gardenreturn selfdef build_garage(self, garage):self.house.garage = garagereturn 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.ppmy.cn/news/1524298.html

相关文章

爬虫4:bs4

对于re来说,公式就是 . ∗ ? .*? .∗?贪婪搜索第一次匹配成功就返回,.*则返回所有成功匹配的 北京新发地尝试 那么对于bs4来说公式就是BeautifulSoup(“html源码”, “html.parser”) import requests from bs4 import BeautifulSoup# url http://…

【OJ】关于顺序表的经典题目(移除数组中指定元素的值、数组去重、合并两个有序的数组)

文章目录 前言题目1:移除数组中指定的元素题目描述解题思路方法1 :暴力法方法2:双指针法 题目2:数组去重题目描述解题思路双指针法 题目3:合并两个有序的数组题目描述解题思路方法1:暴力破解法方法2&#x…

多源BFS之矩阵距离

多源BFS 173. 矩阵距离 给定一个 N行 M列的 01矩阵 A,A[i][j]与 A[k][l]之间的曼哈顿距离定义为dist(i,j,k,l)|i−k||j−l| 输出一个 N行 M列的整数矩阵 B,其中: B[i][j]min1≤x≤N,1≤y≤M,A[x][y]1dist(i,j,x,y) 输入格式 第一行两个整数…

状压DP

状压DP 对于数据范围n<20的可以考虑状压DP 1.蒙德里安的梦想 题目描述 求把 N M NM NM 的棋盘分割成若干个 12 的的长方形&#xff0c;有多少种方案。 例如当$ N2&#xff0c;M4$ 时&#xff0c;共有 5 种方案。当 N 2 &#xff0c; M 3 N2&#xff0c;M3 N2&…

echarts 显示中国地图以及省份

这里使用echarts 4.9的版本显示中国地图&#xff0c;因为5.X的版本已经把地图模块分离出去了 可以从这里下载全国地图数据或各身份的数据 https://github.com/apache/echarts/tree/master/test/data/map 完整代码示例&#xff1a;中国地图 <!DOCTYPE html> <html&g…

全国各地身份证号开头6位数字及地区对照表

具体请前往&#xff1a;全国各地身份证号开头6位数字-省市县/区对照表

设计模式】Listener模式和Visitor模式的区别

文章目录 前言一、介绍Listener模式Visitor模式 二、代码实现2.1 Listener模式的Java实现2.2Listener模式的Go实现2.3Visitor模式的Java实现2.4Visitor模式的Go实现 三、总结 前言 在软件设计中&#xff0c;设计模式是解决特定问题的通用解决方案。Listener模式和Visitor模式是…

STL-stack/queue/deque(容器适配器)

目录 ​编辑 STL-stack 150. 逆波兰表达式求值 stack queue std::stack deque 性能测试 结构 STL-stack 栈的压入、弹出序列_牛客题霸_牛客网输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假。题目…