【设计模式】Head First 设计模式——构建器模式 C++实现
设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。
设计思想
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)
动机
在软件系统中,有时候面临着“一个复杂对象” 的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定
如何应对这种变化,如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保证系统中的“稳定构建算法”不随着需求改变而改变?
结构
要点总结
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;
}
相关文章:

【设计模式】Head First 设计模式——构建器模式 C++实现
设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 设计思想 将一个复杂对象的构建与其表示相分离&…...
基于Python+Django深度学习的身份证识别考勤系统设计与实现
摘 要 我们的生活都是由信息技术在潜移默化的改变着,那么早先改变校园生活的是校园信息化,改变社会人生活是各种应用软件。出行我们依靠的是滴滴,外卖我们依靠的是美团等等。从信息技术的发展至今,各色各样的技术能够满足各类人群…...
Unity控制程序退出
大家好,我是阿赵。 最近把公司的游戏发布到各种PC的游戏大厅,遇到了挺多奇怪的需求。之前介绍了一些Unity发布PC端控制窗口最大最小化、修改exe信息等问题,这次来探讨一下退出游戏的问题。 一、收到奇怪的需求 某游戏大厅要求࿰…...
C++ using的多种用法
1、引入命名空间 using namespace std; using std::cout; 2、引入基类成员 class Base{ public:void func(){cout << "Base::func()" << endl;} }; class Derived : public Base{ public:using Base::func;void func(int x){cout << "Deriv…...

Java环境的安装
最近博主也是在学校开始学习了Java,也通过老师知道了可以通过大学生学生证申(bai)请(piao) IDEA的企业版(社区版也是够学习用的)有很多同学还是没有搞懂便做一下分享。 🌱博客主页:青竹雾色间. 😘博客制作…...

【ES6】js中的__proto__和prototype
在JavaScript中,__proto__和prototype都是用于实现对象继承的关键概念。 1、proto __proto__是一个非标准的属性,用于设置或获取一个对象的原型。这个属性提供了直接访问对象内部原型对象的途径。对于浏览器中的宿主对象和大多数对象来说,可…...

工程项目管理系统源码-简洁+好用+全面-工程项目管理
工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 系统定义 工程项目管理企业不直接与该工程项目的总承包企…...

后端SpringBoot+前端Vue前后端分离的项目(二)
前言:完成一个列表,实现表头的切换,字段的筛选,排序,分页功能。 目录 一、数据库表的设计 编辑二、后端实现 环境配置 model层 mapper层 service层 service层单元测试 controller层 三、前端实现 interface接…...

【5】openGL使用宏和函数进行错误检测
当我们编写openGL程序,没有报编译链接错误,但是运行结果是黑屏,这不是我们想要的。 openGL提供了glGetError 来检查错误,我们可以通过在运行时进行打断点查看glGetError返回值,得到的是一个十进制数,将其转…...

STM32 CAN快速配置(HAL库版本)
STM32 CAN快速配置(HAL库版本) 目录 STM32 CAN快速配置(HAL库版本)前言1 软件编程1.1 初始化1.1.1 引脚设置1.1.2 CAN参数设置1.1.3 CAN滤波器设置 1.2 CAN发送1.3 CAN接收 2 运行测试结束语 前言 控制器局域网总线(CA…...

【文末送书】全栈开发流程——后端连接数据源(二)
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄ÿ…...

leetcode_27_最小栈
class MinStack { public:MinStack() {}void push(int val) {//只要是压栈,先将元素保存到_elem中_elem.push(val);//如果x小于_min中栈顶的元素,将x再压入_min中if(_min.empty() || val < _min.top()){_min.push(val);}}void pop() {//如果——min栈…...
01-ZooKeeper快速入门
1 Zookeeper概念 Zookeeper是Apache Hadoop项目下的一个子项目,是一个树形目录服务。 zookeeper翻译过来就是 动物园管理员,它是用来管理Hadoop(大象)、Hive(蜜蜂)、Pig(小猪)的管…...

[经典面试题]JS的typeof和instanceof区别
一、typeof typeof 是一个一元操作符不是函数,所以不需要传递参数,使用方法非常简单:typeof A 对于基本类型 let s "Nicholas"; let b true; let i 22; let u; let sb undefined; console.log(typeof s); // string console.…...

C++内存区堆和栈
在C中,内存分成5个区,堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。 堆,就是那些…...

QT中闹钟的设置
.h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //按钮 #include <QTextEdit> //文本 #include <QLabel> //标签 #include <QLineEdit> //行编辑器#include <QTimerEvent> //定时器事件类头文件 #…...
【Redis】几款redis可视化工具(推荐Another Redis Desktop Manager)
Redis是一个超精简的基于内存的键值对数据库(key-value),一般对并发有一定要求的应用都用其储存session,乃至整个数据库。不过它公自带一个最小化的命令行式的数据库管理工具,有时侯使用起来并不方便。不过Github上面已经有了很多图形化的管理…...

肖sir__设计测试用例方法之因果图07_(黑盒测试)
设计测试用例方法之因果图 一、定义:因果图提供了一个把规格转化为判定表的系统化方法,从该图中可以产生测试数据。其 中,原因是表示输入条件,结果是对输入执 行的一系列计算后得到的输出。 二、因果图方法最终生成的就是判定表。…...

李宏毅-21-hw3:对11种食物进行分类-CNN
一、代码慢慢阅读理解总结内化: 1.关于torch.nn.covd2d()的参数含义、具体用法、功能: (1)参数含义: 注意,里面的“padding”参数:《both》side所以是上下左右《四》边都会加一个padding数量…...

成集云 | 飞书审批同步金蝶云星空销售订单 | 解决方案
源系统成集云目标系统 方案介绍 飞书是字节跳动于2016年自研的新一代一站式协作平台,将即时沟通、日历、云文档、云盘和工作台深度整合,通过开放兼容的平台,让成员在一处即可实现高效的沟通和流畅的协作,全方位提升企业效率。 …...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...