C++设计模式-Builder 构建器

通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。

一、动机

  • 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定

  • 如何应对这种变化?如何提供一种 “封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

二、模式定义

将一个复杂对象的构建与其表示相分离,使得同样的构建过
程(稳定)可以创建不同的表示(变化)。
——《设计模式》GoF

三、代码示例

我们以房屋为例来展示建造者模式的应用。House类代表房屋对象,而HouseBuilder抽象类定义了构建房屋的步骤。StoneHouseBuilderHouseBuilder的具体实现,用于构建石头房屋。HouseDirector类负责指导具体建造者对象的构建过程。

通过使用建造者模式,我们可以将房屋对象的构建逻辑与客户端代码分离开来。客户端只需要创建一个合适的具体建造者对象,并将其传递给指导者进行构建。这样可以使客户端代码更简洁、可读性更高,并且在需要构建不同类型的房屋时更加灵活和扩展。

#include <iostream>

class House {
public:
    void SetFoundation(const std::string& foundation) {
        this->foundation = foundation;
    }

    void SetWalls(const std::string& walls) {
        this->walls = walls;
    }

    void SetRoof(const std::string& roof) {
        this->roof = roof;
    }

    void SetDoors(const std::string& doors) {
        this->doors = doors;
    }

    void SetWindows(const std::string& windows) {
        this->windows = windows;
    }

    void Show() {
        std::cout << "房屋部分:" << std::endl;
        std::cout << "地基:" << foundation << std::endl;
        std::cout << "墙壁:" << walls << std::endl;
        std::cout << "屋顶:" << roof << std::endl;
        std::cout << "门:" << doors << std::endl;
        std::cout << "窗户:" << windows << std::endl;
    }

private:
    std::string foundation;  // 地基
    std::string walls;       // 墙壁
    std::string roof;        // 屋顶
    std::string doors;       // 门
    std::string windows;     // 窗户
};

class HouseBuilder {
public:
    virtual ~HouseBuilder() {}

    House* GetResult() {
        return pHouse;
    }

    virtual void BuildFoundation() = 0;  // 构建地基
    virtual void BuildWalls() = 0;       // 构建墙壁
    virtual void BuildRoof() = 0;        // 构建屋顶
    virtual void BuildDoors() = 0;       // 构建门
    virtual void BuildWindows() = 0;     // 构建窗户

protected:
    House* pHouse;
};

class StoneHouseBuilder : public HouseBuilder {
public:
    StoneHouseBuilder() {
        pHouse = new House();
    }

    void BuildFoundation() override {
        pHouse->SetFoundation("石头地基");
    }

    void BuildWalls() override {
        pHouse->SetWalls("石头墙壁");
    }

    void BuildRoof() override {
        pHouse->SetRoof("石头屋顶");
    }

    void BuildDoors() override {
        pHouse->SetDoors("木门");
    }

    void BuildWindows() override {
        pHouse->SetWindows("玻璃窗户");
    }
};


class HouseDirector {
public:
    HouseDirector(HouseBuilder* builder) {
        pHouseBuilder = builder;
    }

    House* Construct() {
        pHouseBuilder->BuildFoundation();  // 构建地基
        pHouseBuilder->BuildWalls();       // 构建墙壁
        pHouseBuilder->BuildRoof();        // 构建屋顶
        pHouseBuilder->BuildDoors();       // 构建门
        pHouseBuilder->BuildWindows();     // 构建窗户

        return pHouseBuilder->GetResult();
    }

private:
    HouseBuilder* pHouseBuilder;
};

int main() {
    HouseBuilder* builder = new StoneHouseBuilder();  // 使用石头房屋构建器
    HouseDirector director(builder);
    House* house = director.Construct();  // 构建房屋
    house->Show();  // 展示房屋部分

    delete house;
    delete builder;
    
    return 0;
}

输出:

房屋部分:
地基:石头地基
墙壁:石头墙壁
屋顶:石头屋顶
门:木门
窗户:玻璃窗户

这时候,假如我们有新需求,需要造一个黄金打造的房子,这时候就很方便了,只需要增加GoldenHouseBuilder 建造器,就可以完成这个扩展,不需要更改以前的代码,满足开放-封闭原则

class GoldenHouseBuilder : public HouseBuilder {
public:
    GoldenHouseBuilder() {
        pHouse = new House();
    }

    void BuildFoundation() override {
        pHouse->SetFoundation("黄金地基");
    }

    void BuildWalls() override {
        pHouse->SetWalls("黄金墙壁");
    }

    void BuildRoof() override {
        pHouse->SetRoof("黄金屋顶");
    }

    void BuildDoors() override {
        pHouse->SetDoors("金门");
    }

    void BuildWindows() override {
        pHouse->SetWindows("钻石窗户");
    }
};

调用过程

    HouseBuilder* goldenBuilder = new GoldenHouseBuilder();  // 使用黄金房屋构建器
    HouseDirector goldenDirector(goldenBuilder);
    House* goldenHouse = goldenDirector.Construct();  // 构建黄金房屋
    goldenHouse->Show();  // 展示黄金房屋部分

    delete goldenHouse;
    delete goldenBuilder;

房屋部分:
地基:黄金地基
墙壁:黄金墙壁
屋顶:黄金屋顶
门:金门
窗户:钻石窗户

四、结构

在这里插入图片描述

五、总结

在软件开发过程中,有时候需要构建具有复杂结构的对象。如果直接在客户端代码中创建和配置这些对象,会导致代码变得复杂且难以维护。此外,如果要构建多个具有不同配置的相似对象,每次都重复编写相似的构建代码也是低效的。为了解决这些问题,可以使用建造者模式。

建造者模式的核心思想是将对象的构建过程从其表示中分离出来。它允许你使用相同的构建过程来创建不同的表示形式。该模式将对象的构建委托给一个单独的建造者对象,该对象负责构建对象的各个部分,并最后返回构建好的对象。

在示例代码中,我们以房屋为例来展示建造者模式的应用。House类代表房屋对象,而HouseBuilder抽象类定义了构建房屋的步骤。StoneHouseBuilderGoldenHouseBuilderHouseBuilder的具体实现,分别用于构建石头房屋和黄金房屋。HouseDirector类负责指导具体建造者对象的构建过程。

通过使用建造者模式,我们可以将房屋对象的构建逻辑与客户端代码分离开来。客户端只需要创建一个合适的具体建造者对象,并将其传递给指导者进行构建。这样可以使客户端代码更简洁、可读性更高,并且在需要构建不同类型的房屋时更加灵活和扩展。

建造者模式适用于构建复杂对象的情况,将构建逻辑与表示分离,使得构建过程更加灵活和可扩展。它提供了一种组织和管理对象构建的方式,避免了繁琐和重复的构建代码。通过委托具体的建造者对象来构建对象,客户端代码可以专注于高级操作,而无需关心对象的内部构建细节。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python:(Sentinel-1)如何解析SNAP输出的HDF5文件并输出为GeoTIFF?

博客已同步微信公众号&#xff1a;GIS茄子&#xff1b;若博客出现纰漏或有更多问题交流欢迎关注GIS茄子&#xff0c;或者邮箱联系(推荐-见主页). Python&#xff1a;&#xff08;Sentinel-1&#xff09;如何解析SNAP输出的HDF5文件并输出为GeoTIFF&#xff1f; 01 前言 最近…

MySQL安装——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项——任务2:离线数据处理

MySQLhttps://www.mysql.com/ 将下发的ds_db01.sql数据库文件放置mysql中 12、编写Scala代码&#xff0c;使用Spark将MySQL的ds_db01库中表user_info的全量数据抽取到Hive的ods库中表user_info。字段名称、类型不变&#xff0c;同时添加静态分区&#xff0c;分区字段为etl_da…

TCP单人聊天

TCP和UDP两种通信方式它们都有着自己的优点和缺点 这两种通讯方式不通的地方就是TCP是一对一通信 UDP是一对多的通信方式 TCP通信 TCP通信方式呢 主要的通讯方式是一对一的通讯方式&#xff0c;也有着优点和缺点 它的优点对比于UDP来说就是可靠一点 因为它的通讯方式是需…

谈谈你知道的设计模式?请手动实现单例模式 , Spring 等框架中使用了哪些模式?

文章目录 谈谈你知道的设计模式请手动实现单例模式Spring等框架中使用哪些设计模式&#xff1f;设计模式分类 谈谈你知道的设计模式 我们知道 InputStream 是一个抽象类&#xff0c;标准类库中提供了 FileInputStream、ByteArrayInputStream 等各种不同的子类&#xff0c;分别…

8款AI写作神器,轻松创作高质量内容

随着AI技术的不断发展&#xff0c;AI生成文案平台也逐渐成为一种新型的写作工具。这些平台利用先进的算法和自然语言处理技术&#xff0c;能够快速生成高质量的文案内容。不仅可以提高写作效率&#xff0c;还可以帮助创作者更好地表达思想和创意。AIGCer介绍几款好用的AI写作工…

什么?Figma 的 fig 文件格式居然被破解出来了

大家好&#xff0c;我是前端西瓜哥。 上周图形编辑器交流群里有人问&#xff0c;对于 Figma 导出的 fig 文件&#xff0c;该如何解析其格式&#xff0c;拿到可读数据。 经过群友的一番讨论&#xff0c;这个问题最后算是解决了。 fig 文件 导出 Figma 的设计文件&#xff0c…

智能优化算法应用:基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工电场算法4.实验参数设定5.算法结果6.…

产品调研——AI平台

本文主要记录了对腾讯云-TIONE平台、华为云-ModelArt等主流AI平台的产品调研。 交互式建模 简单点说就是提供了带训练资源的云IDE&#xff0c;使用形态包括Notebook、VsCode等。 腾讯云-TI平台 TI平台将tensorflow、pytorch、spark环境等均集成到一个Notebook容器中&#xf…

深入理解强化学习——马尔可夫决策过程:价值迭代-[价值迭代算法]

分类目录&#xff1a;《深入理解强化学习》总目录 文章《深入理解强化学习——马尔可夫决策过程&#xff1a;价值迭代-[最优性原理]》和文章《深入理解强化学习——马尔可夫决策过程&#xff1a;价值迭代-[确认性价值迭代]》介绍了价值迭代的基础知识&#xff0c;本文将介绍价值…

AX7A200教程(9): ov5640摄像头输出显示720p视频

一&#xff0c;功能框图 ov5640摄像头视频通过ddr3缓存后&#xff0c;最后使用hdmi接口进行输出显示 二&#xff0c;摄像头硬件说明 2.1&#xff0c;像头硬件管脚 如下图所示&#xff0c;一共18个管脚 2.2&#xff0c;摄像头电源初始化时序 因这个ov5640摄像头是买的老摄像…

制造企业MES管理系统可以和AI结合应用吗

在当今的数字化时代&#xff0c;人工智能AI和MES生产管理系统的结合将成为制造企业发展的重要趋势。这种结合可以为制造企业带来许多优势&#xff0c;如提高生产效率、降低成本、优化资源利用等。本文将探讨MES管理系统和AI的结合以及它们在制造企业中的应用&#xff0c;并分析…

【JavaWeb学习笔记】11 - WEB工程路径专题

一、工程路径问题 1.引入该问题 通过这几个去访问很麻烦 二、工程路径解决方案 1.相对路径 1.说明:使用相对路径来解决&#xff0c;一 个非常重要的规则:页面所有的相对路径&#xff0c;在默认情况下&#xff0c;都会参考当前浏览器地址栏的路径http:/ /ip:port/工程名/来进…

BM61 矩阵最长递增路径

题目 矩阵最长递增路径 给定一个 n 行 m 列矩阵 matrix &#xff0c;矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径&#xff0c;使这条路径上的元素是递增的。并输出这条最长路径的长度。 这个路径必须满足以下条件&#xff1a; 1. 对于每个单元格&#xff0c;你…

【基于APB总线的DES实现】

基于APB总线的DES实现 本文内容摘要APB介绍仿真结果整体仿真写入数据DES加密部分DES加密读出密文 整体代码 本文内容摘要 本文是设计一个可兼容APB总线的DES加密协处理器&#xff0c;用来将DES加密模块与APB总线进行对接&#xff0c;使总线发送来的数据可以正常写入并进行加密后…

十四、YARN核心架构

1、目标 &#xff08;1&#xff09;掌握YARN的运行角色和角色之间的关系 &#xff08;2&#xff09;理解使用容器做资源分配和隔离 2、核心架构 &#xff08;1&#xff09;和HDFS架构的对比 HDFS架构&#xff1a; YARN架构&#xff1a;&#xff08;主从模式&#xff09; &…

分类预测 | Matlab实现AOA-SVM算术优化支持向量机的数据分类预测【23年新算法】

分类预测 | Matlab实现AOA-SVM算术优化支持向量机的数据分类预测【23年新算法】 目录 分类预测 | Matlab实现AOA-SVM算术优化支持向量机的数据分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现AOA-SVM算术优化支持向量机的数据分类预测…

Note3---初阶二叉树~~

目录​​​​​​​ 前言&#x1f344; 1.树概念及结构☎️ 1.1 树的概念&#x1f384; 1.2 树的相关概念&#x1f99c; 1.2.1 部分概念的加深理解&#x1f43e; 1.2.2 树与非树&#x1fab4; 1.3 树的表示&#x1f38b; 1.4 树在实际中的运用&#xff08;表示文件系统…

Leetcode—11.盛最多水的容器【中等】

2023每日刷题&#xff08;六十三&#xff09; Leetcode—11.盛最多水的容器 实现代码 #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) int maxArea(int* height, int heightSize) {int left 0, right heightSize - 1;int m…

屏幕超时休眠-Android13

屏幕超时休眠-Android13 1、设置界面1.2 属性值1.2.1 默认值1.2.2 最小值限制 1.3 属性值疑问 Settings.System.SCREEN_OFF_TIMEOUT 2、超时灭屏2.1 锁定屏幕的超时2.2 屏幕灭屏的超时 3、永不休眠* 关键日志 1、设置界面 packages/apps/Settings/src/com/android/settings/dis…

八.创建和管理表

目录 1. 基础知识1.1 一条数据存储的过程1.2 标识符命名规则1.3 MySQL中的数据类型 2. 创建和管理数据库2.2 使用数据库2.3 修改数据库 3. 创建表3.1 创建方式13.2 创建方式23.4 查看数据表结构 4. 修改表4.1 追加一个列4.2 修改一个列4.3 重命名一个列4.4 删除一个列 5. 重命名…