当前位置: 首页 > news >正文

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、定义与动机 定义&#xff1a;将一个复杂对象的构建与其表示相分离&#xff0c;使得同样的构建过程&#xff08;稳定&#xff09;可以创建不同的表示&#xff08;变化&#xff09; 动机&#xff1a; 在软件系统中&#xff0c;有时候面临着“一个复杂对象”的创建工作&#x…...

OJ 【难度1】【Python】完美字符串 扫雷 A-B数对 赛前准备 【C】精密计时

完美字符串 题目描述 你可能见过下面这一句英文&#xff1a; "The quick brown fox jumps over the lazy dog." 短短的一句话就包含了所有 2626 个英文字母&#xff01;因此这句话广泛地用于字体效果的展示。更短的还有&#xff1a; "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进行格式化的功能添加搜索框&#xff0c;回车进行关键词搜索&#xff0c;并对关键词高亮显示搜索到的多个关键词&#xff0c;回车逐一匹配监听json框&#xff0c;如果发生了编辑&#xff0c;需要在退出时提示&#xff0c;在得到用户确认的情况下再退出…...

5分钟了解清楚【osgb】格式的倾斜摄影数据metadata.xml有几种规范

数据格式同样都是osgb&#xff0c;不同软件生产的&#xff0c;建模是参数不一样&#xff0c;还是有很大区别的。尤其在应用阶段。 本文从建模软件、数据组织结构、metadata.xml&#xff08;投影信息&#xff09;、应用几个方面进行了经验性总结。不论您是初步开始建模&#xf…...

CCIE-10-IPv6-TS

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

《QT实用小工具·十七》密钥生成工具

1、概述 源码放在文章末尾 该项目主要用于生成密钥&#xff0c;下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h" #include "qmessag…...

CSP 比赛经验分享

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

探究“大模型+机器人”的现状和未来

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

Commitizen:规范化你的 Git 提交信息

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

官网下载IDE插件并导入IDE

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

三行命令解决Ubuntu Linux联网问题

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

AI大模型在自然语言处理中的应用:性能表现和未来趋势

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

三防平板定制服务:亿道信息与个性化生产的紧密结合

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

【备战蓝桥杯】2024蓝桥杯赛前突击省一:基础数论篇

2024蓝桥杯赛前突击省一&#xff1a;基础算法模版篇 基础数论算法回顾 判断质数&#xff08;试除法&#xff09; 时间复杂度O&#xff08;sqrt(n)&#xff09; 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.因为业务需要查询父文档以及其下子文档&#xff0c;搞了很久才理清楚。 首先还是Inner_hits,inner_hits只能用在nested,has_child,has_parents查询里面 {"query": {"nested": {"path": "comments","query": {"match…...

精准备份:如何自动化单个MySQL数据库的备份过程

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

Green Hills 自带的MULTI调试器查看R7芯片寄存器

Green Hills在查看芯片寄存器时需要导入 .grd文件。下面以R7为例&#xff0c;演示一下过程。 首先打开MULTI调试器&#xff0c;如下所示View->Registers&#xff1a; 进入如下界面&#xff0c;选择导入寄存器定义文件.grd&#xff1a; 以当前R7芯片举例&#xff08;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.结语 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&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及其变体在医学图像分割中得到了广泛应用。然而&#xff0c;这些模型&#xff0c;特别是基于Transformer架构的模型&#xf…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...