【设计模式】Head First 设计模式——构建器模式 C++实现

news2024/12/23 13:40:59

设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。

设计思想

​ 将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)

动机

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

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

结构

img

要点总结

Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“ 分步骤 ”是一个稳定的算法,而复杂对象的各个部分则经常变化

变化点在哪里,封装就在哪里 — Builder 模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动

在Builder 模式中,要注意不同语言中构造器内调用抽象方法的差别。

业务场景

假如你要建房子,建房子需要打地基,需要买建材垒墙,需要造窗户等等,构造一个“房子”对象似乎并不是一件简单的事情…而现在,需要你用不同建材的材料分别去建房子,这些过程一样,但是材料不一样,该如何设计?

代码案例

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class House
{
public:
    House() {}

    ~House()
    {
        cout << "拆房..." << endl;
    }

    void init()
    {
        build1();
        build2();
        if (build3())
        {
            for (int i = 0; i < 4; i++)
            {
                build4(i);
            }
        }
        build5();
    }

protected:
    virtual void build1() const            = 0;
    virtual void build2() const            = 0;
    virtual bool build3() const            = 0;
    virtual void build4(const int i) const = 0;
    virtual void build5() const            = 0;
};

class storeHouse : public House
{
private:
    virtual void build1() const override
    {
        cout << "用石头打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用石头造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "石头房子竣工..." << endl;
    }
};

class glassHouse : public House
{
private:
    virtual void build1() const override
    {
        cout << "用玻璃打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用玻璃造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "玻璃房子竣工..." << endl;
    }
};

class treeHouse : public House
{
private:
    virtual void build1() const override
    {
        cout << "用木头打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用木头造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "木头房子竣工..." << endl;
    }
};

int main()
{
    std::vector<std::shared_ptr<House>> myHouse;
    myHouse.push_back(make_shared<storeHouse>());
    myHouse.push_back(make_shared<glassHouse>());
    myHouse.push_back(make_shared<treeHouse>());
    for (const auto& item : myHouse)
    {
        item->init();
        cout << "-----------------------------" << endl;
    }

    return 0;
}

这里和之前的模板方法模式很像,但是这里把House中的部分属性忽略了,仅仅暴露出其建造过程,于是,如果采用构建器模式,可以单独把建造过程抽出来:

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class House
{
public:
    House() {}

    ~House()
    {
        cout << "拆房..." << endl;
    }

public:
    virtual void build1() const            = 0;
    virtual void build2() const            = 0;
    virtual bool build3() const            = 0;
    virtual void build4(const int i) const = 0;
    virtual void build5() const            = 0;
};

class storeHouse : public House
{
public:
    virtual void build1() const override
    {
        cout << "用石头打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用石头造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "石头房子竣工..." << endl;
    }
};

class glassHouse : public House
{
public:
    virtual void build1() const override
    {
        cout << "用玻璃打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用玻璃造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "玻璃房子竣工..." << endl;
    }
};

class treeHouse : public House
{
public:
    virtual void build1() const override
    {
        cout << "用木头打地基..." << endl;
    }
    virtual void build2() const override
    {
        cout << "用木头造房子..." << endl;
    }
    virtual bool build3() const override
    {
        return cout << "通过质检..." << endl, true;
    }
    virtual void build4(const int i) const override
    {
        cout << "造第" << (i + 1) << "扇窗户" << endl;
    }
    virtual void build5() const override
    {
        cout << "木头房子竣工..." << endl;
    }
};

class HouseBuilder
{
    private:
    std::shared_ptr<House> _house;
    public:
    HouseBuilder(const std::shared_ptr<House>& _house): _house(_house){}

    void init()
    {
        _house->build1();
        _house->build2();
        if (_house->build3())
        {
            for (int i = 0; i < 4; i++)
            {
                _house->build4(i);
            }
        }
        _house->build5();
    }
};

int main()
{
    std::vector<std::shared_ptr<HouseBuilder>> myHouse;
    myHouse.push_back(make_shared<HouseBuilder>(make_shared<storeHouse>()));
    myHouse.push_back(make_shared<HouseBuilder>(make_shared<glassHouse>()));
    myHouse.push_back(make_shared<HouseBuilder>(make_shared<treeHouse>()));
    for (const auto& item : myHouse)
    {
        item->init();
        cout << "-----------------------------" << endl;
    }
    return 0;
}

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

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

相关文章

【两个有序数组合并】

问题描述: 给定两个有序整数数组 A 和 B&#xff0c;将B合并到A中&#xff0c;使得 A 成为一个有序数组。 说明: 初始化 A 和 B 的元素数量分别为 m 和 n。A有足够的空间&#xff08;空间大小大于或等于 m n&#xff09;来保存 B 中的元素。默认升序。 输入输出描述&#xf…

大数据组件-Flume集群环境的启动与验证

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 个人主页&#xff1a;beixi 本文章收录于专栏&#xff08;点击传送&#xff09;&#xff1a;【大数据学习】 &#x1f493;&#x1f493;持续更新中&#xff0c;感谢各位前辈朋友们支持…

《YOLOv5:从入门到实战》专栏介绍 专栏目录

&#x1f31f;YOLOv5&#xff1a;从入门到实战 | 目录 | 使用教程&#x1f31f; 本专栏涵盖了丰富的YOLOv5算法从入门到实战系列教程&#xff0c;专为学习YOLOv5的同学而设计&#xff0c;堪称全网最详细的教程&#xff01;该专栏从YOLOv5基础知识入门到项目应用实战都提供了详细…

JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章

JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章 xxl-job概述windows部署调度中心docker部署调度中心 xxl-job入门案例xxl-job分片广播热点文章定时计算思路分析具体实现热文章计算定时计算 查询文章接口改造来源Gitee xxl-job概述 windows部署调度中心 运行 xxl-job\do…

【数据结构】队列---C语言版(详解!!!)

文章目录 &#x1f438;一、队列的概念及结构&#x1f344;1、队列的概念定义&#x1f344;2、动图演示 &#x1f438;二、队列的实现&#x1f438;三、链表结构队列详解&#x1f34e;创建队列的结构⭕接口1&#xff1a;定义结构体&#xff08;QNode、Queue&#xff09;⭕接口2…

LeetCode 23 合并 K 个升序链表

LeetCode 23 合并 K 个升序链表 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/merge-k-sorted-lists/description/ 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 给你一个链表数组…

中心差分法-学习笔记《结构动力学-陈政清》

激励分段解析法仅仅对外载荷进行了离散&#xff0c;但对运动方程还是严格满足的&#xff0c;体系的运动在时间轴上依然是满足运动微分方程。然而&#xff0c;一般的时域逐步积分法进一步放松要求&#xff0c;不仅仅对外荷载进行离散化处理&#xff0c;也对体系的运动进行离散化…

前端Vue仿企查查天眼查高管信息列表组件

随着技术的不断发展&#xff0c;传统的开发方式使得系统的复杂度越来越高。在传统开发过程中&#xff0c;一个小小的改动或者一个小功能的增加可能会导致整体逻辑的修改&#xff0c;造成牵一发而动全身的情况。为了解决这个问题&#xff0c;我们采用了组件化的开发模式。通过组…

PCL 判断四点共面(三维空间)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里仍然沿用之前的方式来判断三维空间中四个顶点的共面性,三维空间中四个顶点可以构成三条线段(共用同一个顶点),这三条线段所代表的矢量可以组成一个立方空间,如下图所示: 这个立方体的体积其实就是由这三个…

Blender里复制对象动画

假设在Blender里有2个对象&#xff0c;其中一个添加了动画&#xff0c;另外一个没有添加动画&#xff0c;那么如何把已有的动画拷贝到没有动画的对象上呢&#xff1f; 分为2步&#xff1a; 先选中没有动画的对象&#xff0c;再按shift键选中有动画的对象&#xff0c;此时2个对…

【论文精读】Learning Transferable Visual Models From Natural Language Supervision

Learning Transferable Visual Models From Natural Language Supervision 前言Abstract1. Introduction and Motivating Work2. Approach2.1. Creating a Sufficiently Large Dataset2.2. Selecting an Efficient Pre-Training Method2.3. Choosing and Scaling a Model2.4. P…

给Hexo添加说说功能

首发博客地址 官网地址 效果 &#x1f440; 前言 GitHub 仓库&#xff1a;Artitalk.js &#x1f389; 特性 增删查改全方面支持 支持针对每条说说的评论 支持 Markdown/html 语法 支持图片上传 &#x1f680; 快速使用 下列主题已将本项目整合进去&#xff0c;可以直接使用。 感…

Linux——常用命令大汇总(带你快速入门Linux)

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.终端和shell命令解析器终端和shell命令解析器概述终端提示符的格式常用快捷键 二.Linux命令格式帮助文档&#xff1a;man 三.目录基础知识Wind…

什么是RTC

参考&#xff1a; https://zhuanlan.zhihu.com/p/377100294 RTC&#xff08;Real time communication&#xff09;实时通信&#xff0c;是实时音视频的一个简称&#xff0c;我们常说的RTC技术一般指的是WebRTC技术&#xff0c;已经被 W3C 和 IETF 发布为正式标准。由于几乎所…

tableau基础学习2:时间序列数据预处理与绘图

文章目录 数据预处理1. 原始数据2. 合并数据集2. 创建计算字段 绘图分析1. 趋势分析2. 计算字段趋势分析 这一部分&#xff0c;我们记录一些分析时序趋势的分析步骤 数据预处理 1. 原始数据 原始数据是excel表格&#xff0c;其中包含三个Sheet页&#xff0c; 这里我们选择两…

老程序员教你如何笑对问题,轻松培养逻辑思考和解决问题的能力

原文链接 ​​​​​​​老程序员教你如何笑对问题&#xff0c;轻松培养逻辑思考和解决问题的能力 故事发生在一个阳光明媚的午后&#xff0c;我们的主人公&#xff0c;老李&#xff0c;一位拥有十年工作经验的 Python 老程序员&#xff0c;正悠哉地在喝着咖啡。 这时&#x…

VisualStudio配置pybind11-Python调用C++方法

个人测试下来Debug生成的dll改pyd&#xff0c;py中import会报错gilstate->autoInterpreterState 如果遇到同样问题使用Release吧 目录 1.安装pybind11 1.pip&#xff1a; 2.github&#xff1a; 2.配置VS工程 2.在VC目录中的包含目录添加&#xff1a; 3.在VC目录中的库目录…

Debezium的三种部署方式

Debezium如何部署 debezium 有下面三种部署方式,其中最常用的就是 kafka connect。 kafka connect 一般情况下,我们通过 kafka connect 来部署 debezium,kafka connect 是一个框架和运行时: source connectors:像 debezium 这样将记录发送到 kafka 的source connectors…

JavaScript基础语法04——输入输出语法

嗨&#xff0c;大家好&#xff0c;我是雷工。 今天学习JavaScript基础语法&#xff0c;输入输出语法&#xff0c;以下为学习笔记。 1、输出语法&#xff1a; 1.1、alert&#xff08;&#xff09; 作用&#xff1a;界面弹出警告对话框。 示例&#xff1a; <script>aler…

数据结构入门 — 队列

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…