【第四节】C++设计模式(创建型模式)-Builder(建造者)模式

news2025/2/25 3:55:18

目录

引言

一、Builder 模式概述

二、Builder 模式举例

三、Builder 模式的结构

四、Builder 模式的实现

五、Builder 模式的优缺点

六、总结


引言

        Builder 模式是一种创建型设计模式,旨在将复杂对象的构建过程与其表示分离。通过一步步构建对象,Builder 模式允许在构建过程中引入参数,从而生成不同的对象表示。本文将通过理论讲解和代码示例,深入探讨 Builder 模式的核心思想、适用场景及其实现方式。

一、Builder 模式概述

核心思想
        Builder 模式的核心思想是将复杂对象的构建过程分解为多个步骤,并通过一个指导者(Director)对象来协调这些步骤。这样做的好处是:
        构建过程与表示分离:对象的构建过程独立于其最终表示,使得相同的构建过程可以生成不同的对象。
        灵活性:通过在每一步骤中引入参数,可以灵活地调整对象的构建过程。

适用场景
Builder 模式适用于以下场景:
        需要创建的对象非常复杂,由多个部分组成。
        对象的构建过程需要分步骤进行,且每个步骤可能需要不同的参数。
        希望将对象的构建过程与其表示分离,以便生成不同的对象表示。

二、Builder 模式举例

建造一栋房屋是一个复杂的过程,通常分为多个步骤,例如:
        (1)打地基:为房屋奠定基础。
        (2)搭建框架:构建房屋的主体结构。
        (3)安装水电:布置水管、电线等基础设施。
        (4)装修:进行内部和外部的装饰。

每个步骤都需要不同的材料和工艺,且可以根据需求进行调整。例如,地基的深度、框架的材料、装修的风格等都可以根据房屋的用途和预算进行定制。


在房屋建造过程中,Builder 模式可以很好地发挥作用:
        分步骤构建:将房屋的建造过程分解为多个步骤(如打地基、搭建框架等),每个步骤由专门的工人或团队负责。
        参数化构建:在每个步骤中引入不同的参数(如材料选择、设计风格等),从而生成不同的房屋。
        统一管理:通过一个总指挥(Director)来协调各个步骤,确保房屋的建造过程有序进行。


通过 Builder 模式,相同的建造过程可以生成不同的房屋。例如:
        经济型房屋:使用低成本材料,简化装修。
        豪华型房屋:使用高端材料,精心设计装修。
        环保型房屋:采用绿色建材,注重节能设计。


Builder 模式解决的问题与此类似:当我们需要创建的对象非常复杂时,可以通过分步骤构建对象,并在每一步骤中引入参数,从而生成不同的对象表示。

三、Builder 模式的结构

典型结构图


Builder 模式的典型结构包括以下几个角色:
        Product(产品):最终要构建的复杂对象。
        Builder(构建者):定义构建对象的各个步骤的接口。
        ConcreteBuilder(具体构建者):实现 Builder 接口,完成对象的具体构建。
        Director(指导者):负责调用 Builder 的步骤,控制对象的构建过程。

关键点
        分步骤构建:Builder 模式通过分步骤构建对象,使得构建过程更加清晰和可控。
        参数化构建:在每一步骤中引入参数,可以生成不同的对象表示。

四、Builder 模式的实现

代码示例
        以下是一个简单的 Builder 模式实现示例,展示了如何分步骤构建一个复杂对象。


产品类定义

// Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_

class Product {
public:
    Product();
    ~Product();
    void ProducePart();
protected:
private:
};

class ProductPart {
public:
    ProductPart();
    ~ProductPart();
    ProductPart* BuildPart();
protected:
private:
};

#endif // ~_PRODUCT_H_

构建者类定义

// Builder.h
#ifndef _BUILDER_H_
#define _BUILDER_H_
#include <string>
using namespace std;

class Product;

class Builder {
public:
    virtual ~Builder();
    virtual void BuildPartA(const string& buildPara) = 0;
    virtual void BuildPartB(const string& buildPara) = 0;
    virtual void BuildPartC(const string& buildPara) = 0;
    virtual Product* GetProduct() = 0;
protected:
    Builder();
private:
};

class ConcreteBuilder : public Builder {
public:
    ConcreteBuilder();
    ~ConcreteBuilder();
    void BuildPartA(const string& buildPara);
    void BuildPartB(const string& buildPara);
    void BuildPartC(const string& buildPara);
    Product* GetProduct();
protected:
private:
};

#endif // ~_BUILDER_H_

构建者类实现

// Builder.cpp
#include "Builder.h"
#include "Product.h"
#include <iostream>
using namespace std;

Builder::Builder() {}
Builder::~Builder() {}

ConcreteBuilder::ConcreteBuilder() {}
ConcreteBuilder::~ConcreteBuilder() {}

void ConcreteBuilder::BuildPartA(const string& buildPara) {
    cout << "Step1: Build PartA..." << buildPara << endl;
}

void ConcreteBuilder::BuildPartB(const string& buildPara) {
    cout << "Step2: Build PartB..." << buildPara << endl;
}

void ConcreteBuilder::BuildPartC(const string& buildPara) {
    cout << "Step3: Build PartC..." << buildPara << endl;
}

Product* ConcreteBuilder::GetProduct() {
    BuildPartA("pre-defined");
    BuildPartB("pre-defined");
    BuildPartC("pre-defined");
    return new Product();
}

指导者类定义

// Director.h
#ifndef _DIRECTOR_H_
#define _DIRECTOR_H_

class Builder;

class Director {
public:
    Director(Builder* bld);
    ~Director();
    void Construct();
protected:
private:
    Builder* _bld;
};

#endif // ~_DIRECTOR_H_

指导者类实现

// Director.cpp
#include "Director.h"
#include "Builder.h"

Director::Director(Builder* bld) {
    _bld = bld;
}

Director::~Director() {}

void Director::Construct() {
    _bld->BuildPartA("user-defined");
    _bld->BuildPartB("user-defined");
    _bld->BuildPartC("user-defined");
}

测试程序

// main.cpp
#include "Builder.h"
#include "Product.h"
#include "Director.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) {
    Director* d = new Director(new ConcreteBuilder());
    d->Construct();
    return 0;
}

五、Builder 模式的优缺点

优点
        构建过程与表示分离:对象的构建过程独立于其最终表示,使得相同的构建过程可以生成不同的对象。
        灵活性:通过在每一步骤中引入参数,可以灵活地调整对象的构建过程。
        易于扩展:新增构建步骤或调整构建顺序非常方便。

缺点
        复杂性增加:随着构建步骤的增多,Builder 模式的实现可能变得复杂。
        代码冗余:每个具体构建者类都需要实现相同的构建步骤接口,可能导致代码冗余。

六、总结

        Builder 模式是一种强大的设计模式,适用于复杂对象的构建。它通过分步骤构建对象,并将构建过程与表示分离,提供了灵活性和可扩展性。然而,在面对简单对象的构建时,Builder 模式可能显得过于复杂。因此,在实际开发中,应根据具体需求选择合适的设计模式。

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

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

相关文章

本地部署AI模型 --- DeepSeek(二)---更新中

目录 FAQ 1.Failed to load the model Exit code: 18446744072635812000 FAQ 1.Failed to load the model Exit code: 18446744072635812000 问题描述&#xff1a; &#x1f972; Failed to load the model Error loading model. (Exit code: 18446744072635812000). Unkn…

MariaDB 历史版本下载地址 —— 筑梦之路

MariaDB 官方yum源里面只有目前在维护的版本&#xff0c;而有时候对于老项目来说还是需要老版本的rpm包&#xff0c;国内很多镜像站都是同步的官方仓库&#xff0c;因此下载老版本也不好找&#xff0c;这里主要记录下从哪里可以下载到历史版本的MariaDB rpm包。 1. 官方归档网…

Qt中使用QPdfWriter类结合QPainter类绘制并输出PDF文件

一.类的介绍 1.QPdfWriter介绍 Qt中提供了一个直接可以处理PDF的类&#xff0c;这就是QPdfWriter类。 &#xff08;1&#xff09;PDF文件生成 支持创建新的PDF文件或覆盖已有文件&#xff0c;通过构造函数直接绑定文件路径或QFile对象&#xff1b; 默认生成矢量图形PDF&#…

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流

在现代工作与学习中&#xff0c;可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本&#xff0c;结合 Typora 快速生成流程图和甘特图&#xff0c;并通过 Markdown 格式生成思维导图&#xff0c;最终…

Oracle 连接报错:“ORA-12541:TNS:no listener ”,服务组件中找不到监听服务

一、 报错&#xff1a; navicat连接数据库报错&#xff1a;ORA-12541&#xff1a;TNS:no listener 二、排查问题 三、 解决问题 删除Oracle安装目录下选中的配置&#xff1a;listener.ora 及 listener*.bak相关的 cmd&#xff0c;用管理员打开 执行&#xff1a;netca 命…

一文详解U盘启动UEFI/Legacy方式以及GPT/MBR关系

对于装系统的老手而说一直想研究一下装系统的原理&#xff0c;以及面对一些问题时的解决思路&#xff0c;故对以前的方法进行原理上的解释&#xff0c;主要想理解其底层原理。 引导模式 MBR分区可以同时支持UEFI和Legacy引导&#xff0c;我们可以看一下微pe制作的启动盘&#…

计算机毕设-基于springboot的汽车配件销售管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

嵌入式八股文(五)硬件电路篇

一、名词概念 1. 整流和逆变 &#xff08;1&#xff09;整流&#xff1a;整流是将交流电&#xff08;AC&#xff09;转变为直流电&#xff08;DC&#xff09;。常见的整流电路包括单向整流&#xff08;二极管&#xff09;、桥式整流等。 半波整流&#xff1a;只使用交流电的正…

C语言番外篇(3)------------>break、continue

看到我的封面图的时候&#xff0c;部分读者可能认为这和编程有什么关系呢&#xff1f; 实际上这个三个人指的是本篇文章有三个部分组成。 在之前的博客中我们提及到了while循环和for循环&#xff0c;在这里面我们学习了它们的基本语法。今天我们要提及的是关于while循环和for…

Mac下Python版本管理,适用于pyenv不起作用的情况

前言 声明&#xff1a;之前也在网上看到过可以使用pyenv来管理python版本&#xff0c;但由于作者的python安装路径实在是繁杂不堪&#xff0c;因此安装完成pyenv体验下来没有任何用处&#xff0c;但偶然发现vscode似乎可以看到各个python版本&#xff0c;因此写下这篇博客记录…

网络安全知识--网络、网络安全产品及密码产品概述

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 网络结构 网络设备&#xff1a;交换机、路由器、负载均衡 安全设备&#xff1a; 通信网络安全类:通信安全、网络监测与控制 区域边界安全类&#xff1a;隔离类…

WiFi相关功能使用教程(wpa_supplicant及wpa_cli)

WiFi相关功能使用教程(wpa_supplicant及wpa_cli) 在之前的博客文中&#xff0c;我们已经成功交叉编译了wpa_supplicant和wpa_cli相关文件。 此篇文章中我们将介绍如何使用和配置WiFi模块。 先将生成的可执行文件拷贝到设备里 采用TFTP的方式拷贝到设备中并全都加上可执行权限…

CentOS7 离线安装 Postgresql 指南

一、背景 服务器通常都是离线内网环境&#xff0c;想要通过联网方式一键下载安装 Postgresql 不太现实&#xff0c;本文将介绍如何在 CentOS7 离线安装 Postgresql&#xff0c;以及遇到困难如何解决。 二、安装包下载 先在本地下载好 rpm 包&#xff0c;再通过 ftp 上传到服…

C/C++后端开发面经

字节跳动 客户端开发 实习 一面(50min) 自我介绍是否愿意转语言,是否只愿意搞后端选一个项目来详细谈谈HTTP和HTTPS有什么区别?谈一下HTTPS加密的具体过程&#xff1a; 非对称加密 对称加密 证书认证的方式 非对称加密是为了保证对称密钥的安全性。 对称…

路由器的WAN口和LAN口有什么区别?

今时今日&#xff0c;移动终端盛行的时代&#xff0c;WIFI可以说是家家户户都有使用到的网络接入方式。那么路由器当然也就是家家户户都不可或缺的设备了。而路由器上的两个实现网络连接的基础接口 ——WAN 口和 LAN 口&#xff0c;到底有什么区别&#xff1f;它们的功能和作用…

CSS通过webkit-scrollbar设置滚动条样式

查看::-webkit-scrollbar-*各项关系 以下图为例&#xff0c;可以分别定义滚动条背景、滚动轨道、滚动滑块的样式。 需要先给外部容器设置高度&#xff0c;再设置overflow: auto&#xff0c;最后设置三个webkit属性。 <!DOCTYPE html> <html lang"en">…

Seata1.5.2学习(二)——使用分布式事务锁@GlobalLock

目录 一、创建数据库 二、配置consumer-service 1.pom.xml 2.application.properties 3.启动类 4.其他代码 三、配置provider-service 1.pom.xml 2.application.properties 3.启动类 4.其他代码 四、分布式事务问题演示与解决办法 (一)分布式事务问题演示 (二)…

华为 网络安全 认证

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 华为 网络安全 认证&#xff1a;保障信息安全的重要一环 在数字化时代的今天&#xff0c;网络安全成为了企业和个人都需要高度重视的问题。尤其是在企业信息化的…

网络运维学习笔记 019 HCIA-Datacom综合实验03

文章目录 综合实验3实验需求一&#xff1a;A公司网络规划二&#xff1a;B公司网络规划 配置一、ip、vlan、vlanif&#xff0c;stp、eth-trunkSW1SW2SW3R1 二、ospfSW1R1 三、NATR1ISP 四、拒绝ping允许httpSW1 五、右半部分vlan、dhcp、ospf、NATSW4R2 综合实验3 实验需求 一&…

网络运维学习笔记 015网工初级(HCIA-Datacom与CCNA-EI)NAT网络地址转换

文章目录 NAT(Network Address Translation&#xff0c;网络地址转换)思科&#xff1a;1&#xff09;PAT2&#xff09;静态端口转换 华为&#xff1a;1&#xff09;EasyIP2&#xff09;NAT Server静态NAT&#xff1a;动态NAT&#xff1a;实验1&#xff1a;在R1上配置NAPT让内网…