Python设计模式:构建模式

1. 什么是构建模式

构建模式(Builder Pattern)是一种创建型设计模式,它允许使用多个简单的对象一步步构建一个复杂的对象。构建模式通过将构建过程与表示分离,使得同样的构建过程可以创建不同的表示。换句话说,构建模式提供了一种灵活的方式来创建复杂对象,避免了构造函数参数过多的问题。

  • 工厂模式通过一个工厂类来创建对象,适合于创建多个相似对象,隐藏了对象创建的具体实现。
  • 构建模式通过构建者和指挥者的组合,逐步构建一个复杂对象,适合于需要多个步骤和多个部分的组合。
  • 组合模式则允许将对象组合成树形结构,适合于处理部分和整体的层次关系。

1.1 工厂模式与构建模式的对比

在工厂模式中,我们将创建一个简单的汽车工厂来生成汽车对象。

class Car:def __init__(self, make, model):self.make = makeself.model = modeldef __str__(self):return f"{self.make} {self.model}"class CarFactory:@staticmethoddef create_car(make, model):return Car(make, model)# 客户端代码
if __name__ == "__main__":car1 = CarFactory.create_car("Toyota", "Camry")car2 = CarFactory.create_car("Honda", "Accord")print(car1)  # 输出: Toyota Camryprint(car2)  # 输出: Honda Accord

在构建模式中,我们将使用构建者模式逐步构建一个复杂的汽车对象。

# 产品类
class Car:def __init__(self):self.make = Noneself.model = Noneself.year = Noneself.color = Nonedef __str__(self):return f"{self.year} {self.color} {self.make} {self.model}"# 构建者接口
class CarBuilder:def set_make(self, make):passdef set_model(self, model):passdef set_year(self, year):passdef set_color(self, color):passdef build(self):pass# 具体构建者
class ConcreteCarBuilder(CarBuilder):def __init__(self):self.car = Car()def set_make(self, make):self.car.make = makedef set_model(self, model):self.car.model = modeldef set_year(self, year):self.car.year = yeardef set_color(self, color):self.car.color = colordef build(self):return self.car# 指挥者
class Director:def __init__(self, builder):self.builder = builderdef construct_car(self, make, model, year, color):self.builder.set_make(make)self.builder.set_model(model)self.builder.set_year(year)self.builder.set_color(color)return self.builder.build()# 客户端代码
if __name__ == "__main__":builder = ConcreteCarBuilder()director = Director(builder)# 构建一辆车car = director.construct_car("Toyota", "Camry", 2022, "Blue")print(car)  # 输出: 2022 Blue Toyota Camry

1.2 组合模式与构建模式的对比

在组合模式中,我们将创建一个文件系统的结构,允许文件和文件夹以树形结构组合。

class Component:def operation(self):passclass File(Component):def __init__(self, name):self.name = namedef operation(self):return f"File: {self.name}"class Folder(Component):def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def operation(self):results = [f"Folder: {self.name}"]for child in self.children:results.append(child.operation())return "\n".join(results)# 客户端代码
if __name__ == "__main__":file1 = File("file1.txt")file2 = File("file2.txt")folder1 = Folder("Folder 1")folder1.add(file1)folder1.add(file2)print(folder1.operation())

在构建模式中,我们将使用构建者模式逐步构建一个复杂的文件对象。

class File:def __init__(self, name):self.name = namedef __str__(self):return f"File: {self.name}"class Folder:def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def __str__(self):results = [f"Folder: {self.name}"]for child in self.children:results.append(str(child))return "\n".join(results)class FileBuilder:def __init__(self):self.folder = Nonedef create_folder(self, name):self.folder = Folder(name)def add_file(self, file_name):if self.folder:self.folder.add(File(file_name))def build(self):return self.folder# 客户端代码
if __name__ == "__main__":builder = FileBuilder()builder.create_folder("Folder 1")builder.add_file("file1.txt")builder.add_file("file2.txt")folder = builder.build()print(folder)  # 输出: Folder: Folder 1\nFile: file1.txt\nFile: file2.txt

2. 构建模式的结构

构建模式通常包含以下几个角色:

  1. 产品(Product):表示被构建的复杂对象。
  2. 构建者(Builder):定义了创建产品的抽象接口,包含构建产品的各个部分的方法。
  3. 具体构建者(ConcreteBuilder):实现了构建者接口,负责构建产品的具体部分。
  4. 指挥者(Director):负责管理构建过程,使用构建者来构建产品。
# 产品类
class Car:def __init__(self):self.make = Noneself.model = Noneself.year = Noneself.color = Nonedef __str__(self):return f"{self.year} {self.color} {self.make} {self.model}"# 构建者接口
class CarBuilder:def set_make(self, make):passdef set_model(self, model):passdef set_year(self, year):passdef set_color(self, color):passdef build(self):pass# 具体构建者
class ConcreteCarBuilder(CarBuilder):def __init__(self):self.car = Car()def set_make(self, make):self.car.make = makedef set_model(self, model):self.car.model = modeldef set_year(self, year):self.car.year = yeardef set_color(self, color):self.car.color = colordef build(self):return self.car# 指挥者
class Director:def __init__(self, builder):self.builder = builderdef construct_car(self, make, model, year, color):self.builder.set_make(make)self.builder.set_model(model)self.builder.set_year(year)self.builder.set_color(color)return self.builder.build()# 客户端代码
if __name__ == "__main__":builder = ConcreteCarBuilder()director = Director(builder)# 构建一辆车car = director.construct_car("Toyota", "Camry", 2022, "Blue")print(car)  # 输出: 2022 Blue Toyota Camry
  1. 产品类(Car):表示被构建的复杂对象,包含多个属性(如品牌、型号、年份和颜色),并实现了一个 __str__ 方法用于输出对象的字符串表示。

  2. 构建者接口(CarBuilder):定义了创建产品的抽象接口,包含设置汽车各个属性的方法。

  3. 具体构建者(ConcreteCarBuilder):实现了构建者接口,负责实现构建汽车的具体部分。它创建一个 Car 对象并逐步设置其属性,最后返回构建好的 Car 对象。

  4. 指挥者(Director):负责管理构建过程,使用构建者来构建产品。它接受一个构建者对象,并通过调用构建者的方法来构建一个完整的 Car 对象。

  5. 客户端代码:创建了一个 ConcreteCarBuilder 实例和一个 Director 实例。通过指挥者的 construct_car 方法,逐步构建了一辆汽车,并最终输出了构建好的汽车对象。

3. 示例 1:构建复杂的餐厅订单系统

在日常开发中,构建模式常用于构建复杂对象的场景。一个典型的例子是餐厅订单系统。在这个系统中,顾客可以选择不同的菜品、饮料和配餐,最终生成一个完整的订单。使用构建模式可以有效地管理这个复杂的构建过程。

在这个示例中,我们将创建一个订单对象,顾客可以通过不同的步骤来构建这个订单。我们将定义以下角色:

  1. 产品(Order):表示顾客的订单,包含多个菜品和饮料。
  2. 构建者(OrderBuilder):定义了创建订单的抽象接口,包含添加菜品和饮料的方法。
  3. 具体构建者(ConcreteOrderBuilder):实现了构建者接口,负责构建订单的具体部分。
  4. 指挥者(Director):负责管理构建过程,使用构建者来构建订单。
# 产品类
class Order:def __init__(self):self.dishes = []self.drinks = []def add_dish(self, dish):self.dishes.append(dish)def add_drink(self, drink):self.drinks.append(drink)def __str__(self):order_details = "Order Details:\n"order_details += "Dishes:\n" + "\n".join(self.dishes) + "\n"order_details += "Drinks:\n" + "\n".join(self.drinks)return order_details# 构建者接口
class OrderBuilder:def add_dish(self, dish):passdef add_drink(self, drink):passdef build(self):pass# 具体构建者
class ConcreteOrderBuilder(OrderBuilder):def __init__(self):self.order = Order()def add_dish(self, dish):self.order.add_dish(dish)def add_drink(self, drink):self.order.add_drink(drink)def build(self):return self.order# 指挥者
class Director:def __init__(self, builder):self.builder = builderdef construct_order(self, dishes, drinks):for dish in dishes:self.builder.add_dish(dish)for drink in drinks:self.builder.add_drink(drink)return self.builder.build()# 客户端代码
if __name__ == "__main__":builder = ConcreteOrderBuilder()director = Director(builder)# 构建一个订单dishes = ["Spaghetti", "Caesar Salad", "Grilled Chicken"]drinks = ["Coke", "Water"]order = director.construct_order(dishes, drinks)print(order)  # 输出订单详情
Order Details:
Dishes:
Spaghetti
Caesar Salad
Grilled Chicken
Drinks:
Coke
Water
  1. 产品类(Order):表示顾客的订单,包含多个菜品和饮料。它提供了添加菜品和饮料的方法,并实现了一个 __str__ 方法用于输出订单的详细信息。

  2. 构建者接口(OrderBuilder):定义了创建订单的抽象接口,包含添加菜品和饮料的方法。

  3. 具体构建者(ConcreteOrderBuilder):实现了构建者接口,负责构建订单的具体部分。它创建一个 Order 对象并逐步添加菜品和饮料,最后返回构建好的订单对象。

  4. 指挥者(Director):负责管理构建过程,使用构建者来构建订单。它接受一个构建者对象,并通过调用构建者的方法来构建一个完整的订单对象。

  5. 客户端代码:创建了一个 ConcreteOrderBuilder 实例和一个 Director 实例。通过指挥者的 construct_order 方法,逐步构建了一个订单,并最终输出了订单的详细信息。

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

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

相关文章

使用 VIM 编辑器对文件进行编辑

一、VIM 的两种状态 VIM(vimsual)是 Linux/UNIX 系列 OS 中通用的全屏编辑器。vim 分为两种状态,即命令状态和编辑状态,在命令状态下,所键入的字符系统均作命令来处理;而编辑状态则是用来编辑文本资料&…

GaussDB回调机制深度实践:从事件驱动到系统集成

GaussDB回调机制深度实践:从事件驱动到系统集成 一、回调机制核心概念 回调类型矩阵 二、核心实现技术栈 触发器回调开发 sql -- 创建审计触发器回调 CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGININSERT INTO audit_log (operati…

AI小白:AI算法中常用的数学函数

文章目录 一、激活函数1. Sigmoid2. ReLU(Rectified Linear Unit)3. Tanh(双曲正切)4. Softmax示例代码:激活函数的实现 二、损失函数1. 均方误差(MSE)2. 交叉熵损失(Cross-Entropy&…

idea 打不开terminal

IDEA更新到2024.3后Terminal终端打不开的问题_idea terminal打不开-CSDN博客

Python代码list列表的使用和常用方法及增删改查

Python代码list列表的使用和常用方法及增删改查 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有:学习and理解的关联性,希望对您有用~ python语法-p…

Open CASCADE学习|读取点集拟合样条曲线(续)

问题 上一篇文章已经实现了样条曲线拟合,但是仍存在问题,Tolerance过大拟合成直线了,Tolerance过大头尾波浪形。 正确改进方案 1️⃣ 核心参数优化 通过调整以下参数控制曲线平滑度: Standard_Integer DegMin 3; // 最低阶…

Python基础知识点(列表与字典)

列表list[] # list [12,34,56,78] # print(list) """ 1.list可以保存同一类型的数据 或 不同类型的数据 2.list是有序的,所以可以通过[下标]访问元素 3.list保存重复的值 4.list是可变的,可以添加 删除元素 """ …

在 Elasticsearch 中使用 Amazon Nova 模型

作者:来自 Elastic Andre Luiz 了解如何在 Elasticsearch 中使用 Amazon Nova 系列模型。 在本文中,我们将讨论 Amazon 的 AI 模型家族——Amazon Nova,并学习如何将其与 Elasticsearch 结合使用。 关于 Amazon Nova Amazon Nova 是 Amazon …

MySQL8.0.40编译安装(Mysql8.0.40 Compilation and Installation)

MySQL8.0.40编译安装 近期MySQL发布了8.0.40版本,与之前的版本相比,部分依赖包发生了变化,因此重新编译一版,也便于大家参考。 1. 下载源码 选择对应的版本、选择源码、操作系统 如果没有登录或者没有MySQL官网账号&#xff0…

python中pyside6多个py文件生成exe

网上见到的教程大多数都是pyinstaller安装单个py文件,针对多个py文件的打包,鲜有人提及;有也是部分全而多的解释,让人目不暇接,本次记录自己设置一个声波捕捉界面的打包过程。 1.pycharm中调用pyinstaller打包 参考链接:https://blog.csdn.net/weixin_45793544/articl…

Java中使用Function Call实现AI大模型与业务系统的集成​

这个理念实际上很早就出现了,只不过早期的模型推理理解能力比较差,用户理解深度预测不够,现在每天的迭代有了改进,逐步引入到我们本身的业务系统,让AI大模型集成进来管理自身业务功能。当然现在也不是一个什么难事了。…

id 属性自动创建 js 全局变量

给一个元素设置 id 属性&#xff0c;它会在 js 中创建全局变量&#xff0c;如 <div class"test" click"test" id"idTest">test</div>test() {console.log(idTest:, window.idTest) }.test {height: 50px;width: 200px;background-c…

Android SELinux权限使用

Android SELinux权限使用 一、SELinux开关 adb在线修改seLinux(也可以改配置文件彻底关闭) $ getenforce; //获取当前seLinux状态,Enforcing(表示已打开),Permissive(表示已关闭) $ setenforce 1; //打开seLinux $ setenforce 0; //关闭seLinux二、命令查看sel…

【R语言绘图】圈图绘制代码

绘制代码 rm(list ls())# 加载必要包 library(data.table) library(circlize) library(ComplexHeatmap) library(rtracklayer) library(GenomicRanges) library(BSgenome) library(GenomicFeatures) library(dplyr)### 数据准备阶段 ### # 1. 读取染色体长度信息 df <- re…

vim 编辑器 使用教程

Vim是一款强大的文本&#xff08;代码&#xff09;编辑器&#xff0c;它是由Bram Moolenaar于1991年开发完成。它的前身是Bill Joy开发的vi。名字的意义是Vi IMproved。 打开vim&#xff0c;直接在命令行输入vim即可&#xff0c;或者vim <filename>. Vim分为四种模式&a…

C++20新增内容

C20 是 C 语言的一次重大更新&#xff0c;它引入了许多新特性&#xff0c;使代码更现代化、简洁且高效。以下是 C20 的主要新增内容&#xff1a; 1. 概念&#xff08;Concepts&#xff09; 概念用于约束模板参数&#xff0c;使模板编程更加直观和安全。 #include <concept…

C++中常用的十大排序方法之4——希尔排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之4——希尔排序的相…

详细描述以太坊的gas、gaslimit、gasPrice

目录 一、Gas 是什么? ✅ 简要定义: 🧠 举例理解: 二、Gas Limit 是什么? ✅ 简要定义: 分两种: 举例说明: 三、Gas Price 是什么? ✅ 简要定义: 为什么它重要? 示例: 四、 EIP-1559 后的新机制(伦敦升级) 三个要素: 五、额外技巧(开发实用) 本文…

全国大学生数学建模竞赛赛题深度分析报告(2010-2024)

全国大学生数学建模竞赛赛题深度分析报告&#xff08;2010-2024&#xff09; 全国大学生数学建模竞赛(CUMCM)是中国最具影响力的大学生科技竞赛之一&#xff0c;本报告将对2010-2024年间的赛题进行全面统计分析&#xff0c;包括题目类型、领域分布、模型方法等多个维度&#x…

从奖励到最优决策:动作价值函数与价值学习

从奖励到最优决策&#xff1a;动作价值函数与价值学习 价值学习一、动作价值函数对 U t U_t Ut​求期望得到动作价值函数动作价值函数的意义最优动作价值函数(Optimal Action-Value Function)如何理解 Q ∗ Q^* Q∗函数 二、价值学习的基本思想Deep Q-Network(DQN)DQN玩游戏的具…