设计模式- 建造者模式(Builder Pattern)结构|原理|优缺点|场景|示例

news/2024/9/25 19:18:15/

 目录

        设计模式(分类)        设计模式(六大原则)   

    创建型

        工厂方法         抽象工厂模式        单例模式        建造者模式        原型模式

     结构型

        适配器模式

建造者模式(Builder Pattern)是一种创建型设计模式,其主要目的是将复杂对象的构建过程与它的表示分离,使得相同的构建过程可以创建不同的表示。这种模式适用于创建包含多个可选部件、步骤复杂且可能需要逐步构建的复杂对象,它能将构建过程分解为多个独立的、可复用的步骤,使得对象的创建过程更加清晰、灵活且易于扩展。

模式结构

建造者模式通常包含以下角色:

  • 产品(Product):表示要构建的复杂对象,包含多个组成部件。
  • 抽象建造者(Abstract Builder):定义创建产品各个部件的接口,并声明一个方法返回最终的完整产品。
  • 具体建造者(Concrete Builders):实现抽象建造者的接口,提供创建产品各个部件的详细实现,并在最后返回一个完整的具体产品实例。
  • 导演者(Director):负责调用具体建造者的相关方法来一步步构建产品,它不涉及具体产品的部件创建细节,只负责按特定顺序安排建造过程。

工作原理

  • 客户端:创建一个具体建造者实例,并将其交给导演者。客户端不直接与产品交互,而是通过导演者指定构建过程。
  • 导演者:持有具体建造者实例,调用其方法按照预定的步骤构建产品。导演者不关心具体建造者的内部实现细节,只关注构建过程的顺序。
  • 具体建造者:实现抽象建造者接口,提供构建产品各个部件的方法。每个具体建造者对应一种产品的不同构建方式。
  • 产品:定义产品的组成部分和接口,供外界使用。具体建造者通过构建产品的各个部件来创建完整的产品实例。

优缺点

优点
  • 封装性:将复杂对象的构建过程封装在建造者内部,与对象的表示分离,使客户端无需了解对象的内部构造细节。
  • 灵活性:可以通过改变具体建造者来改变产品的内部结构,无需修改导演者和客户端代码,符合“开闭原则”。
  • 可扩展性:易于扩展以构建不同类型的复杂对象,只需增加新的具体建造者即可。
  • 可复用性:抽象建造者和具体建造者可以被多个导演者重用,构建过程可以独立于使用过程。
缺点
  • 代码复杂度增加:引入了多个类(抽象建造者、具体建造者、导演者),增加了系统的复杂性,对于简单的对象构建可能显得过度设计。
  • 产品结构固化:如果产品的内部结构需要频繁变动,可能需要不断修改建造者,维护成本较高。

适用场景

  • 对象构建过程复杂:当对象的创建涉及多个步骤,且这些步骤的顺序和组合可能有多种变化时,适合使用建造者模式。
  • 需要灵活改变产品内部结构:当需要构建的产品内部结构可变,或者存在多种不同结构的产品需要构建时,建造者模式可以提供灵活的构建方式。
  • 构建过程独立于使用过程:当构建过程与产品的使用过程分离,且构建过程需要独立封装时,建造者模式能够很好地满足需求。

代码示例(以Java为例)

java">// 产品(复杂对象)
class Computer {private String cpu;private String ram;private String hdd;public Computer(String cpu, String ram, String hdd) {this.cpu = cpu;this.ram = ram;this.hdd = hdd;}@Overridepublic String toString() {return "Computer{" +"cpu='" + cpu + '\'' +", ram='" + ram + '\'' +", hdd='" + hdd + '\'' +'}';}
}// 抽象建造者
interface ComputerBuilder {void buildCPU(String cpu);void buildRAM(String ram);void buildHDD(String hdd);Computer build();
}// 具体建造者
class DesktopBuilder implements ComputerBuilder {private String cpu;private String ram;private String hdd;@Overridepublic void buildCPU(String cpu) {this.cpu = cpu;}@Overridepublic void buildRAM(String ram) {this.ram = ram;}@Overridepublic void buildHDD(String hdd) {this.hdd = hdd;}@Overridepublic Computer build() {return new Computer(cpu, ram, hdd);}
}// 导演者
class Director {public Computer constructComputer(ComputerBuilder builder) {builder.buildCPU("Intel i7");builder.buildRAM("16GB DDR4");builder.buildHDD("1TB SSD");return builder.build();}
}// 客户端代码
public class Main {public static void main(String[] args) {Director director = new Director();ComputerBuilder desktopBuilder = new DesktopBuilder();Computer computer = director.constructComputer(desktopBuilder);System.out.println(computer); // 输出:Computer{cpu='Intel i7', ram='16GB DDR4', hdd='1TB SSD'}}
}

在这个Java示例中:

  • Computer类是复杂的产品对象,包含CPU、RAM和HDD三个部件。
  • ComputerBuilder接口定义了构建计算机各个部件的方法,以及返回完整计算机对象的方法。
  • DesktopBuilder类实现了ComputerBuilder接口,提供了构建计算机部件的具体实现。
  • Director类负责调用DesktopBuilder的构建方法,按照特定顺序构建计算机,并返回构建完成的计算机对象。
  • 客户端代码通过Director来构建计算机,无需关心具体的构建细节。如果需要构建不同类型的计算机(如笔记本电脑),只需创建新的具体建造者类并传递给Director即可。

代码示例(以Python为例) 

# 产品(复杂对象)
class Computer:def __init__(self, cpu, ram, hdd):self.cpu = cpuself.ram = ramself.hdd = hdddef __str__(self):return f"Computer(cpu={self.cpu}, ram={self.ram}, hdd={self.hdd})"# 抽象建造者
class ComputerBuilder:def build_cpu(self, cpu):raise NotImplementedError("Subclasses must implement this method")def build_ram(self, ram):raise NotImplementedError("Subclasses must implement this method")def build_hdd(self, hdd):raise NotImplementedError("Subclasses must implement this method")def build(self):raise NotImplementedError("Subclasses must implement this method")# 具体建造者
class DesktopBuilder(ComputerBuilder):def __init__(self):self.cpu = Noneself.ram = Noneself.hdd = Nonedef build_cpu(self, cpu):self.cpu = cpudef build_ram(self, ram):self.ram = ramdef build_hdd(self, hdd):self.hdd = hdddef build(self):return Computer(self.cpu, self.ram, self.hdd)# 导演者
class Director:def construct_computer(self, builder):builder.build_cpu("Intel i7")builder.build_ram("16GB DDR4")builder.build_hdd("1TB SSD")return builder.build()# 客户端代码
def main():director = Director()builder = DesktopBuilder()computer = director.construct_computer(builder)print(computer)  # 输出:Computer(cpu=Intel i7, ram=16GB DDR4, hdd=1TB SSD)if __name__ == "__main__":main()

在这个Python示例中:

  • Computer类是复杂的产品对象,包含CPU、RAM和HDD三个部件,并提供了__str__方法以便打印输出。
  • ComputerBuilder类作为抽象建造者,定义了构建计算机各个部件的方法(build_cpubuild_rambuild_hdd)以及返回完整计算机对象的build方法,这些方法在抽象类中均抛出NotImplementedError,要求子类必须实现。
  • DesktopBuilder类继承自ComputerBuilder,实现了具体构建计算机部件的方法,并在build方法中返回一个新建的Computer实例。
  • Director类负责调用DesktopBuilder的构建方法,按照特定顺序构建计算机,并返回构建完成的计算机对象。
  • 客户端代码通过Director来构建计算机,无需关心具体的构建细节。如果需要构建不同类型的计算机(如笔记本电脑),只需创建新的具体建造者类并传递给Director即可。

http://www.ppmy.cn/news/1426661.html

相关文章

使用 Python 从 PDF 文件中提取、转换图像

目录: 从 PDF 中提取图像将 PDF 页面转换为图像 本文的任务是从 PDF 文件中提取图像,并使用 Python 中将 PDF 页面转换为图像。为了实现使用 Python 从 PDF 文件中提取图像,需要安装使用 Fitz、PyMuPDF 库。 Fitz 库是一个图像处理库&#xf…

vue2响应式 VS vue3响应式

Vue2响应式 存在问题: 新增属性,删除属性,界面不会更新。 直接通过下标修改数组界面不会自动更新。 Vue2使用object.defineProperty来劫持数据是否发生改变,如下: 能监测到获取和修改属性: 新增的属性…

“手撕“三大特性之一的<继承>(上)

目录 一、为什么需要继承 二、什么是继承 三、继承怎么写 四、成员的访问 1.父类与子类的成员变量不同名 2.父类与子类的成员变量同名 3.父类与子类的成员方法不同名 4.父类与子类的成员方法同名 五、super关键字 一、为什么需要继承 先让我们看一段Java代码&#…

Spring AI ETL 流水线

先纠正 Spring AI 使用本地 Ollama Embeddings 中的一个错误,当启动 Ollama 之后,Windows会有托盘图标,此时已经启动了 Ollama 的服务,访问 Embedding 时不需要运行 ollama run gemma ,只有访问 chat 时才需要启动一个…

富文本插入图片的时候直接复制链接的风险点和解决方案

业务背景 最近由于项目需要开发了一个富文本的功能其中有一个小点是插入图片到富文本中, 插入的时候是可以直接复制图片的链接地址插入的我本来觉得没啥,但是感觉哪里不太对,于是开始了风险点评估,以及对应的解决方案 风险点评…

openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置

文章目录 openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置265.1安装openEuler操作系统265.2 修改操作系统内核PAGESIZE为64KB。265.3 关闭CPU中断的服务irqbalance openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置 本…

Dual-AMN论文阅读

Boosting the Speed of Entity Alignment 10: Dual Attention Matching Network with Normalized Hard Sample Mining 将实体对齐速度提高 10 倍:具有归一化硬样本挖掘的双重注意力匹配网络 ABSTRACT 寻找多源知识图谱(KG)中的等效实体是知识图谱集成的关键步骤&…

共享软件工厂:软件行业的“滴滴打车”模式

在数字化浪潮席卷全球的背景下,软件行业正面临着前所未有的挑战与机遇。传统软件开发模式由于需求变化快、交付周期长、人才流动性大、迭代升级困难等问题,已经难以满足市场快速变化的需求。在这个关键的时刻,共享软件工厂应运而生&#xff0…