(一)创建型设计模式:3、建造者模式(Builder Pattern)

news/2025/1/19 14:08:17/

目录

1、建造者模式含义

2、建造者模式的讲解

3、使用C++实现建造者模式的实例

4、建造者模式的优缺点

5、建造者模式VS工厂模式


1、建造者模式含义

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.

将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

其实上面这句话本身是有点晦涩难懂,后面在网上看到有人这样说,便留下深刻的印象:

当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

这个解释也可以理解为应用场景,当我们单纯懂得设计模式怎么实现并不重要,重要的是要知道适用于什么场景,这个就得靠一些经验和思考了。

2、建造者模式的讲解

从上面的UML可以看出,建造者模式涉及到以下四个角色的概念:

(1)抽象建造者角色:提供一个接口,规范产品对象的建造,一般由子类实现。一般来说,产品的组成部分数与建造方法数相同,即有多少组成部分,就有多少个建造方法。

(2)具体建造者角色:该角色实现了抽象建造者抽象建造者接口,主要是实现所有声明的方法以及返回建造好的产品实例。

(3)导演者角色:负责调用具体建造者按照顺序建造产品。导演者只负责调度,真正执行的是具体建造者角色。

(4)产品角色:该角色是建造的复杂对象,提供基本方法。

3、使用C++实现建造者模式的实例


#include <iostream>
#include <string>// 产品类
class Product {
public:void setPartA(const std::string& partA) {m_partA = partA;}void setPartB(const std::string& partB) {m_partB = partB;}void setPartC(const std::string& partC) {m_partC = partC;}void show() const {std::cout << "Product Parts: " << m_partA << ", " << m_partB << ", " << m_partC << std::endl;}private:std::string m_partA;std::string m_partB;std::string m_partC;
};// 抽象建造者类
class Builder {
public:virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product* getResult() = 0;
};// 具体建造者类
class ConcreteBuilder : public Builder {
public:void buildPartA() override {m_product->setPartA("Part A");}void buildPartB() override {m_product->setPartB("Part B");}void buildPartC() override {m_product->setPartC("Part C");}Product* getResult() override {return m_product;}private:Product* m_product = new Product();
};// 指挥者类
class Director {
public:void construct(Builder* builder) {builder->buildPartA();builder->buildPartB();builder->buildPartC();}
};int main() {Director director;ConcreteBuilder builder;director.construct(&builder);Product* product = builder.getResult();product->show();delete product;return 0;
}

在上述示例中,我们定义了一个产品类(Product),它有三个部分(Part A、Part B、Part C)。然后,我们定义了一个抽象建造者类(Builder),其中包含了构建产品各个部分的纯虚函数。接着,我们实现了具体的建造者类(ConcreteBuilder),它实现了抽象建造者类的纯虚函数,并负责构建产品对象。最后,我们定义了一个指挥者类(Director),它负责调用建造者的方法来构建产品。

在主函数中,我们创建了一个具体的建造者对象,并将其传递给指挥者对象。指挥者根据具体的建造者对象来构建产品,最终得到一个完整的产品对象。我们可以通过产品对象的show()方法来展示产品的各个部分。

这就是一个简单的建造者模式的C++源码示例

4、建造者模式的优缺点

(1)优点:

1)分离构建过程和表示:建造者模式可以将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。这样可以提高代码的灵活性和可维护性。

2)更好的封装性:通过建造者模式,可以将对象的构建过程封装在具体的建造者类中,客户端只需要与指挥者进行交互,无需关心具体的构建细节。这样可以隐藏对象的创建过程,提供更好的封装性。

3)可以控制构建过程:建造者模式允许你逐步构建对象,并在每个步骤中进行必要的操作、检查或验证。这样可以更加灵活地控制对象的构建过程,满足不同的需求。

4)创建不同表示形式的对象:通过定义不同的建造者和指挥者,可以根据需求定制不同的构建过程,创建不同的产品表示形式。这样可以提供更多的选择和灵活性。

(2)缺点:

1)增加了代码量:使用建造者模式会增加额外的类和接口,从而增加了代码量。如果对象的构建过程比较简单,使用建造者模式可能会显得过于繁琐。

2)增加了系统复杂性:引入建造者模式会增加系统的复杂性,因为需要定义多个类和接口,并且需要协调指挥者和建造者之间的关系。这可能会增加理解和维护的难度。

3)不适用于创建简单对象:如果对象的构建过程比较简单,只有少量的步骤或参数,使用建造者模式可能会显得过于繁琐。此时,直接使用简单工厂或工厂方法模式可能更加合适。

总的来说,建造者模式通过分离构建过程和表示,提供了更好的封装性和灵活性,可以控制构建过程并创建不同表示形式的对象。然而,它也增加了代码量和系统复杂性,不适用于创建简单对象。

5、建造者模式VS工厂模式

建造者模式和工厂模式是两种常见的创建型设计模式,它们有以下几点区别:

(1)目的不同:工厂模式关注的是创建对象的过程,将对象的创建逻辑封装在一个工厂类中,通过工厂类来创建具体的对象。而建造者模式关注的是创建复杂对象的过程,将对象的构建过程与其表示分离,通过指挥者和建造者来逐步构建对象。

(2)对象复杂度不同:工厂模式适用于创建简单对象,通常只需要一两个步骤即可完成对象的创建。而建造者模式适用于创建复杂对象,对象的构建过程需要多个步骤,并且可以根据需求定制不同的构建过程。

(3)调用方式不同:工厂模式通过调用工厂类的方法来创建对象,客户端直接与工厂类交互。而建造者模式通过指挥者来控制建造者的构建过程,客户端只需要与指挥者进行交互,无需直接与建造者类交互。

(4)灵活性不同:工厂模式相对较为灵活,可以根据需要扩展和添加新的产品类型,只需要添加对应的具体产品和工厂类即可。而建造者模式相对更加灵活,可以根据需要定制不同的构建过程,创建不同的产品表示形式。

总的来说,工厂模式适用于创建简单对象,将对象的创建过程封装在工厂类中;而建造者模式适用于创建复杂对象,通过指挥者和建造者来分步构建对象。
 


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

相关文章

C# Blazor 学习笔记(12):css样式设置

文章目录 前言添加引入css保证razor和css的对应关系手动引入css文件 前言 由于Blazor UI库暂时还不完善&#xff0c;有时候需要我们自己写css。Razor做好了css动态隔离的设置。 ASP.NET Core Blazor CSS 隔离 C#小轮子&#xff1a;Visual Studio自动编译Sass文件 添加引入c…

matlab使用教程(11)—创建随机数

MATLAB 使用算法来生成伪随机数和伪独立数。这些数在数学意义上并非严格随机和独立的&#xff0c;但它们能够通过各种随机和独立统计测试&#xff0c;并且其计算可以重复&#xff0c;方便用于测试或诊断目的。 rand 、 randi 、 randn 和 randperm 函数是创建随机数数组的主要…

oracle基础语法和备份恢复

Oracle总结 sql命令分类 1.DDL&#xff0c;数据定义语言&#xff0c;create创建/drop销毁 2.DCL&#xff0c;数据库控制语言&#xff0c;grant授权/revoke撤销 3.DML&#xff0c;数据操纵语言&#xff0c;insert/update/delete等sql语句 4.DQL&#xff0c;数据查询语言&am…

SQL Server 查询数据并汇总相关技巧 23.08.08

GROUPING 是一个聚合函数,它产生一个附加的列&#xff0c;当用 CUBE 或 ROLLUP 运算符添加行时&#xff0c;附加的列输出值为1&#xff0c;当所添加的行不是由 CUBE 或 ROLLUP 产生时&#xff0c;附加列值为0。 仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相联系的选择…

Cobbler自定义yum源

再次了解下Cobbler的目录结构&#xff1a; 在/var/www/cobbler/ks_mirror目录下存放的是所有的镜像。 存放的是仓库镜像&#xff1a; 在/var/lib/cobbler/kickstarts目录下是存放的所有的kickstarts文件。 再有就是/etc/cobbler这个目录&#xff1a; [rootvm1 loaders]# cd /…

解决: git拉取报错 git 未能顺利结束 (退出码 1)

拉取代码失败信息 解决方法: 执行一下"git push -f origin master"命令即可 步骤: 1.项目文件夹右击选择"Git Bash Here",打开命令窗口 2. 输入"git push -f origin master"后,回画 执行结束 3.再拉取代码,成功

第一百一十回 如何实现动画

文章目录 概念介绍实现方法示例代码经验分享 我们在上一章回中介绍了转场动画相关的内容&#xff0c;本章回中将介绍 如何实现动画.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 提到动画相信大家都不陌生&#xff0c;在程序中使用动画可以增加程序酷炫的效果&a…

C#类型转换

&#x1f35f;数据类型 大体分为三个大类型&#xff1a;整型&#xff08;其中又分为有符号整型、无符号整型&#xff09;、浮点型、特殊类型 注意&#xff1a;浮点数在初始化时要在值后加上后缀&#xff0c;双精度浮点数decimal的后缀为“M”、单精度浮点数double和float的后…