C++设计模式:构建器模式(九)
1、定义与动机
-
定义:将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)
-
动机:
- 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构建而成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定
- 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?
-
个人理解:构建器模式严格来说是在Template Method方法的基础上进行拆分,将表示和构建过程相分离拆成一个更加复杂但耦合度更低的代码。
2、案例分析
- 假设需要构建一栋房子,需要墙、窗户、房顶、地板等需求,但是所需要的房子是木头还是石头还是其他材料的房子并不清楚
- 可以很容易的使用Template Method模式写出一个伪代码,解决依赖倒置问题即可。
2.1、模板方法(一)
class House{
public:void Init(){// 构建墙this->BuilderWall();// 构建四个窗户for(int i = 0;i < 4;i++){this->BuilderWindows();}// 是否需要铺地板if(this->BuilderFlag()){this->BuilderFloor();}// 构建房顶this->BuilderRoof();}virtual ~House(){}
protected:virtual void BuilderWall() = 0;virtual void BuilderWindows() = 0;virtual bool BuilderFlag() = 0;virtual void BuilderFloor() = 0;virtual void BuilderRoof() = 0;
};class StoneHouse: public House{
public:virtual ~StoneHouse(){}
protected:virtual void BuilderWall(){}virtual void BuilderWindows(){}virtual bool BuilderFlag(){return true;}virtual void BuilderFloor(){}virtual void BuilderRoof(){}
};int main()
{House *house = new StoneHouse();house->Init();
}
其实这个代码写到这里已经可以了,可以不继续优化也不需要使用构建器模式。
2.2、构建器模式
- 一个类的功能不能太复杂太过于庞大,当类的行为代码太多时可以考虑重构,将对象的表示和构建过程分离提取多个单独的类
- 具体思路:
- House和HouseBuilder基类,分别是一个东西的表示和构建过程
- 对于House基类可以有多种多样的House,StoneHouse、WoodHouse、CrystalHouse…
- 对于HouseBuilder基类为每种房子的构建提供具体的Builder构建器,其应该组合一个House基类
- 由于构建房子的一个基本流程(算法骨架)是大致相同(相对稳定)的,因此可以将这个大致流程(算法骨架)单独提取出一个类,通过多态的性质传入不同的XXXHouseBuilder构建器进行构建不同的房子。
class House{
protected:Wall wall;Window window;
public:virtual ~House(){}// ...
};class StoneHouse: public House{
public:virtual ~StoneHouse(){}
};class HouseBuilder{
public:House* GetResult(){return house;}virtual ~HouseBuilder(){}
protected:House *house;virtual void BuilderWall() = 0;virtual void BuilderWindows() = 0;virtual bool BuilderFlag() = 0;virtual void BuilderFloor() = 0;virtual void BuilderRoof() = 0;
};class StoneHouseBuilder: public HouseBuilder{
protected:virtual void BuilderWall(){
// house->wall;...}virtual void BuilderWindows(){
// house->window;...}virtual bool BuilderFlag(){}virtual void BuilderFloor(){}virtual void BuilderRoof(){}
};class HouseDirector{
public:HouseBuilder* houseBuilder;HouseDirector(HouseBuilder* _houseBuilder): houseBuilder(_houseBuilder){}House *Construct(){// 构建墙houseBuilder->BuilderWall();// 构建四个窗户for(int i = 0;i < 4;i++){houseBuilder->BuilderWindows();}// 是否需要铺地板if(houseBuilder->BuilderFlag()){houseBuilder->BuilderFloor();}// 构建房顶houseBuilder->BuilderRoof();return houseBuilder->GetResult();}
};
3、总结
- Builder模式主要用于“分步构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
- 变化点在哪里,封装哪里——Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。(稳定点就是缺点)
- Builder模式中,需要注意不同语言中构造器内部调用虚函数的差别(C++ vs Java)
- C++中无法再父类的构造方法中调用子类的虚函数(动态绑定),因为子类在此时还没有构造出来,此时如果在构造方法中调用虚函数,那么将会是静态绑定,意味着调用父类自己的虚函数。而Java等语言不是
相关文章:

C++设计模式:构建器模式(九)
1、定义与动机 定义:将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化) 动机: 在软件系统中,有时候面临着“一个复杂对象”的创建工作&#x…...

OJ 【难度1】【Python】完美字符串 扫雷 A-B数对 赛前准备 【C】精密计时
完美字符串 题目描述 你可能见过下面这一句英文: "The quick brown fox jumps over the lazy dog." 短短的一句话就包含了所有 2626 个英文字母!因此这句话广泛地用于字体效果的展示。更短的还有: "The five boxing wizards…...

【Tars-go】腾讯微服务框架学习使用01--初始化服务
1 初始INIT-Demo运行 按照官网描述 go get 安装框架依赖 # < go 1.16 go get -u github.com/TarsCloud/TarsGo/tars/tools/tarsgo go get -u github.com/TarsCloud/TarsGo/tars/tools/tars2go # > go 1.16 go install github.com/TarsCloud/TarsGo/tars/tools/tarsgolat…...

通过pre标签进行json格式化展示,并实现搜索高亮和通过鼠标进行逐个定位的功能
功能说明 实现一个对json进行格式化的功能添加搜索框,回车进行关键词搜索,并对关键词高亮显示搜索到的多个关键词,回车逐一匹配监听json框,如果发生了编辑,需要在退出时提示,在得到用户确认的情况下再退出…...

5分钟了解清楚【osgb】格式的倾斜摄影数据metadata.xml有几种规范
数据格式同样都是osgb,不同软件生产的,建模是参数不一样,还是有很大区别的。尤其在应用阶段。 本文从建模软件、数据组织结构、metadata.xml(投影信息)、应用几个方面进行了经验性总结。不论您是初步开始建模…...

CCIE-10-IPv6-TS
目录 实验条件网络拓朴 环境配置开始Troubleshooting问题1. R25和R22邻居关系没有建立问题2. 去往R25网络的下一跳地址不存在、不可用问题3. 去往目标网络的下一跳地址不存在、不可用 实验条件 网络拓朴 环境配置 在我的资源里可以下载(就在这篇文章的开头也可以下…...

《QT实用小工具·十七》密钥生成工具
1、概述 源码放在文章末尾 该项目主要用于生成密钥,下面是demo演示: 项目部分代码如下: #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h" #include "qmessag…...

CSP 比赛经验分享
中国软件专业技术资格(水平)考试( CSP-S )是一项旨在评价软件和信息技术 专业人员专业技术水平的考试。对于参加过 CSP 比赛的人来说,这是一个展示 自己编程能力、逻辑思维和解决问题能力的好机会。下面是一些基于…...

探究“大模型+机器人”的现状和未来
基础模型(Foundation Models)是近年来人工智能领域的重要突破,在自然语言处理和计算机视觉等领域取得了显著成果。将基础模型引入机器人学,有望从感知、决策和控制等方面提升机器人系统的性能,推动机器人学的发展。由斯坦福大学、普林斯顿大学…...

Commitizen:规范化你的 Git 提交信息
简介 在团队协作开发过程中,规范化的 Git 提交信息可以提高代码维护的效率,便于追踪和定位问题。Commitizen 是一个帮助我们规范化 Git 提交信息的工具,它提供了一种交互式的方式来生成符合约定格式的提交信息。 原理 Commitizen 的核心原…...

官网下载IDE插件并导入IDE
官网下载IDEA插件并导入IDEA 1. 下载插件2. 导入插件 1. 下载插件 地址:https://plugins.jetbrains.com/plugin/21068-codearts-snap/versions 说明:本次演示以IDEA软件为例 操作: 等待下载完成 2. 导入插件 点击File->setting->Pl…...

三行命令解决Ubuntu Linux联网问题
本博客中Ubuntu版本为23.10.1最新版本,后续发现了很多问题我无法解决,已经下载了另外一个版本22.04,此版本自带网络 一开始我找到官方文档描述可以通过命令行连接到 WiFi 网络:https://cn.linux-console.net/?p10334#google_vig…...

AI大模型在自然语言处理中的应用:性能表现和未来趋势
引言 A. AI大模型在自然语言处理中的应用背景简介 近年来,随着深度学习和人工智能技术的快速发展,越来越多的研究人员和企业开始关注应用于自然语言处理的AI大模型。这些模型采用了深层的神经网络结构,具有强大的学习和处理能力,…...

三防平板定制服务:亿道信息与个性化生产的紧密结合
在当今数字化时代,个性化定制已经成为了市场的一大趋势,而三防平板定制服务作为其中的一部分,展现了数字化技术与个性化需求之间的紧密结合。这种服务是通过亿道信息所提供的技术支持,为用户提供了满足特定需求的定制化三防平板&a…...

【备战蓝桥杯】2024蓝桥杯赛前突击省一:基础数论篇
2024蓝桥杯赛前突击省一:基础算法模版篇 基础数论算法回顾 判断质数(试除法) 时间复杂度O(sqrt(n)) static int is_prime(int n){if(n<2) return 0;for (int i2;i<n/i;i){if(n%i0) return 0;}return 1; }质因…...

golang es查询的一些操作,has_child,inner_hit,对索引内父子文档的更新
1.因为业务需要查询父文档以及其下子文档,搞了很久才理清楚。 首先还是Inner_hits,inner_hits只能用在nested,has_child,has_parents查询里面 {"query": {"nested": {"path": "comments","query": {"match…...

精准备份:如何自动化单个MySQL数据库的备份过程
自动化备份对于维护数据库的完整性和安全性至关重要。本指南将向您展示如何使用Shell脚本来自动化MySQL数据库的备份过程。 备份脚本内容 首先,这是我们将使用的备份脚本: #!/bin/bash# 完成数据库的定时备份 # 备份路径 BACKUP/data/backup/db # 当前…...

Green Hills 自带的MULTI调试器查看R7芯片寄存器
Green Hills在查看芯片寄存器时需要导入 .grd文件。下面以R7为例,演示一下过程。 首先打开MULTI调试器,如下所示View->Registers: 进入如下界面,选择导入寄存器定义文件.grd: 以当前R7芯片举例(dr7f7013…...

Jupyter Notbook如何安装配置并结合内网穿透实现无公网IP远程连接使用
文章目录 推荐1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂&am…...

LightM-UNet:Mamba 辅助的轻量级 UNet 用于医学图像分割
文章目录 摘要1 简介2、方法论2.1、架构概述2.2、编码器块2.3、瓶颈块2.4、解码器块 3、实验4、结论 摘要 https://arxiv.org/pdf/2403.05246.pdf UNet及其变体在医学图像分割中得到了广泛应用。然而,这些模型,特别是基于Transformer架构的模型…...

探索 Java 网络爬虫:Jsoup、HtmlUnit 与 WebMagic 的比较分析
1、引言 在当今信息爆炸的时代,网络数据的获取和处理变得至关重要。对于 Java 开发者而言,掌握高效的网页抓取技术是提升数据处理能力的关键。本文将深入探讨三款广受欢迎的 Java 网页抓取工具:Jsoup、HtmlUnit 和 WebMagic,分析…...

day16 java object中equals、finalize、
Object类 1.Object类是所有类的父类。 2.一个类如果没有显示继承其它类默认继承Object类equals方法 1.Object中的equals方法 - 用来比较地址值 public boolean equals(Object obj) { return (this obj); } 2.像核心类库中的许多类都重写了equals方法(比如&…...

如何应用电桥电路的原理?
电桥电路是一种常用的测量技术,它利用了四个电阻的网络来检测电路的平衡状态。在平衡状态下,电桥的输出电压为零,这种特性使得电桥电路非常适合于精确测量电阻、电感、电容等电气参数,以及用于传感器和测量设备中。以下是电桥电路…...

大话设计模式——24.迭代器模式(Iterator Pattern)
简介 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部实现。(Java中使用最多的设计模式之一) UML图 应用场景 Java的集合对象:Collection、List、Map、Set等都有迭代器Java ArrayList的迭代器源码 示例 简…...

【数据结构】双向链表 C++
一、什么是双向链表 1、定义 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。 双…...

消息队列之-----------------zookeeper机制
目录 一、ZooKeeper是什么 二、ZooKeeper的工作机制 三、ZooKeeper特点 四、ZooKeeper数据结构 五、ZooKeeper应用场景 5.1统一命名服务 5.2统一配置管理 5.3统一集群管理 5.4服务器动态上下线 5.5软负载均衡 六、ZooKeeper的选举机制 6.1第一次启动选举机制 6.2非…...

第十届蓝桥杯大赛个人赛省赛(软件类) CC++ 研究生组2.0
A立方和 #include<iostream> #include<cmath> using namespace std; int main(){int n, t, flag, x;long long ans 0;for(int i 1; i < 2019; i){t i;flag 0;while(t && !flag){x t % 10;if(x 2 || x 0 || x 1 || x 9) flag 1;t / 10;}if(fl…...

vscode开发ESP32问题记录
vscode 开发ESP32问题记录 1. 解决vscode中的波浪线警告 1. 解决vscode中的波浪线警告 参考链接:https://blog.csdn.net/fucingman/article/details/134404485 首先可以通过vscode 中的IDF插件生成模板工程,这样会自动创建.vscode文件夹中的一些json配…...

R语言复现:轨迹增长模型发表二区文章 | 潜变量模型系列(2)
培训通知 Nhanes数据库数据挖掘,快速发表发文的利器,你来试试吧!欢迎报名郑老师团队统计课程,4.20直播。 案例分享 2022年9月,中国四川大学学者在《Journal of Psychosomatic Research》(二区,I…...

【数据结构】顺序表的实现——动态分配
🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:数据结构 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…...