「软件设计模式」建造者模式(Builder)

深入解析建造者模式:用C++打造灵活对象构建流水线
引言:当对象构建遇上排列组合
在开发复杂业务系统时,你是否经常面对这样的类:它有20个成员变量,其中5个是必填项,15个是可选项。当用户需要创建豪华套餐A(含加冰可乐)或基础套餐B(不要洋葱)时,传统的构造函数早已不堪重负。这正是建造者模式(Builder Pattern)大展拳脚的舞台!
一、模式精髓解析
建造者模式通过分步构建的方式解耦复杂对象的创建过程,让同一构建流程能产出不同表现形式的产品。就像麦当劳的点餐系统:选择汉堡基底→添加配料→选择饮料→完成套餐组合。
二、C++模式实现结构

核心组件拆解
- Product(产品):需要构建的复杂对象
- Builder(抽象建造者):定义构建步骤的接口
- ConcreteBuilder(具体建造者):实现具体构建逻辑
- Director(指挥者):控制构建流程(可选)
三、实战:定制汉堡套餐系统
我们以快餐店汉堡套餐系统为例,演示如何实现不同配置的套餐组合。
1. 产品类定义
#include <iostream>
#include <memory>
#include <string>
#include <vector>class HamburgerMeal {
public:void showMeal() const {std::cout << "=== 您的套餐配置 ===" << std::endl;std::cout << "主餐: " << mainItem << std::endl;std::cout << "饮料: " << drink << std::endl;std::cout << "附加项: ";for (const auto& item : sides) {std::cout << item << " ";}std::cout << "\n甜点: " << (dessert.empty() ? "无" : dessert) << std::endl;}private:friend class MealBuilder; // 允许建造者访问私有成员std::string mainItem;std::string drink;std::vector<std::string> sides;std::string dessert;
};
2. 建造者实现
class MealBuilder {
public:MealBuilder() = default;MealBuilder& setMain(const std::string& main) {meal.mainItem = main;return *this;}MealBuilder& setDrink(const std::string& drink) {meal.drink = drink;return *this;}MealBuilder& addSide(const std::string& side) {meal.sides.push_back(side);return *this;}MealBuilder& setDessert(const std::string& dessert) {meal.dessert = dessert;return *this;}HamburgerMeal build() {// 验证必要参数if (meal.mainItem.empty()) {throw std::invalid_argument("必须指定主餐");}return meal;}private:HamburgerMeal meal;
};
3. 客户端调用
#include "../../include/header.h"
#include "buger.h"
#include "meal_builder.h"
int main() {try {// 豪华套餐HamburgerMeal premiumMeal = MealBuilder().setMain("安格斯牛肉汉堡").setDrink("大杯可乐").addSide("薯条").addSide("鸡块").setDessert("苹果派").build();// 简约套餐HamburgerMeal simpleMeal = MealBuilder().setMain("经典鸡腿堡").setDrink("小杯雪碧").build();premiumMeal.showMeal();std::cout << "\n";simpleMeal.showMeal();} catch (const std::exception& e) {std::cerr << "套餐创建失败: " << e.what() << std::endl;}return 0;
}
4.执行结果

四、高级技巧:支持多种预设配置
class MealPreset {
public:static HamburgerMeal createChildrenMeal() {return MealBuilder().setMain("迷你汉堡").setDrink("牛奶").addSide("水果杯").setDessert("小饼干").build();}static HamburgerMeal createComboMeal() {return MealBuilder().setMain("双层牛肉堡").setDrink("中杯可乐").addSide("薯条").build();}
};
五、模式优势深度解析
🚀 C++实现特色优势
- 强类型检查:编译期发现类型错误
- RAII支持:自动资源管理
- 移动语义:高效的对象传递
- 灵活内存控制:支持栈对象和智能指针
💡 适用场景扩展
- 需要生成的对象有多个变体
- 对象创建需要多个步骤的初始化
- 需要隔离复杂对象的创建细节
- 需要支持不同地区配置(如语言包加载)
六、性能优化策略
- 参数预校验:在build()前进行参数检查
- 使用移动语义:减少对象拷贝开销
- 对象池技术:对频繁创建的对象进行缓存
- const正确性:确保构建后的对象不可变
七、与工厂模式对比
| 特性 | 建造者模式 | 工厂模式 |
|---|---|---|
| 构建重点 | 分步骤构建复杂对象 | 直接创建完整对象 |
| 参数处理 | 支持可选参数和分步设置 | 通常需要一次性传递所有参数 |
| 对象复杂度 | 适合构建多部件组成的复杂对象 | 适合创建单一结构的对象 |
| 扩展性 | 通过新增Builder实现不同配置 | 通过子类化工厂来创建不同对象 |
| 典型C++实现 | 链式方法+友元类 | 静态工厂方法/抽象工厂 |
八、现代C++增强实现
// 使用现代C++特性优化建造者
template<typename T>
class GenericBuilder {
protected:T object;public:operator T() && { // 右值转换运算符return std::move(object);}T build() && { // 右值build方法return std::move(object);}
};class ModernMeal : public GenericBuilder<ModernMeal> {
public:ModernMeal& setMain(std::string main) {object.mainItem = std::move(main);return *this;}// 其他设置方法类似...
};
九、最佳实践指南
- 防御性编程:在build()中进行参数合法性检查
- 清晰的接口设计:保持方法命名直观(withXxx(), addXxx())
- 不可变对象:构建完成后锁定对象状态
- 文档注释:明确每个构建步骤的作用域和约束条件
- 异常安全:确保在异常发生时资源正确释放
总结:构建的艺术
建造者模式如同一位经验丰富的建筑大师,将看似混乱的构建过程转化为标准化的装配流程。在C++的世界中,通过合理运用友元类、移动语义和模板技术,我们能够打造出既高效又灵活的对象构建系统。记住,好的设计模式应用应该像呼吸一样自然,而不是生硬的教条堆砌。
相关文章:
「软件设计模式」建造者模式(Builder)
深入解析建造者模式:用C打造灵活对象构建流水线 引言:当对象构建遇上排列组合 在开发复杂业务系统时,你是否经常面对这样的类:它有20个成员变量,其中5个是必填项,15个是可选项。当用户需要创建豪华套餐A&…...
Matlab 机器人 雅可比矩阵
工业机器人运动学与Matlab正逆解算法学习笔记(用心总结一文全会)(四)——雅可比矩阵_staubli机器人正逆向运动学实例验证matlab-CSDN博客 matlab求雅可比矩阵_六轴机械臂 矢量积法求解雅可比矩阵-CSDN博客 (63 封私信 / 80 条消息…...
DeepSeek 助力 Vue 开发:打造丝滑的面包屑导航(Breadcrumbs)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
IntelliJ IDEA 2024.1.4版无Tomcat配置
IntelliJ IDEA 2024.1.4 (Ultimate Edition) 安装完成后,调试项目发现找不到Tomcat服务: 按照常规操作添加,发现服务插件中没有Tomcat。。。 解决方法 1、找到IDE设置窗口 2、点击Plugins按钮,进入插件窗口,搜索T…...
chrome://version/
浏览器输入: chrome://version/ Google浏览器版本号以及安装路径 Google Chrome131.0.6778.205 (正式版本) (64 位) (cohort: Stable) 修订版本81b36b9535e3e3b610a52df3da48cd81362ec860-refs/branch-heads/6778_155{#8}操作系统Windows…...
知识图谱数据库 Neo4j in Docker笔记
下载 docker pull neo4j:community官方说明 https://neo4j.com/docs/operations-manual/2025.01/docker/introduction/ 启动 docker run \--restart always \--publish7474:7474 --publish7687:7687 \--env NEO4J_AUTHneo4j/your_password \--volumeD:\files\knowledgegrap…...
【动手学强化学习】02多臂老虎机
问题定义 强化学习关注的是在于环境交互中学习,是一种试错学习的范式。在正式进入强化学习之前,我们先来了解多臂老虎机问题。该问题也被看作简化版的强化学习,帮助我们更快地过度到强化学习阶段。 有一个拥有 K K K 根拉杆的老虎机&#…...
【网络编程】之Udp网络通信步骤
【网络编程】之Udp网络通信步骤 TCP网络通信TCP网络通信的步骤对于服务器端对于客户端 TCP实现echo功能代码实现服务器端getsockname函数介绍 客户端效果展示 对比两组函数 TCP网络通信 TCP网络通信的步骤 对于服务器端 创建监听套接字。(调用socket函数ÿ…...
Java 基于 SpringBoot+Vue 的家政服务管理平台设计与实现
博主介绍:✌程序员徐师兄、8年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战*✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
架构——Nginx功能、职责、原理、配置示例、应用场景
以下是关于 Nginx 的功能、职责、原理、配置示例、应用场景及其高性能原因的详细说明: 一、Nginx 的核心功能 1. 静态资源服务 功能:直接返回静态文件(如 HTML、CSS、JS、图片、视频等)。配置示例:server {listen 80…...
Spring Boot中使用Flyway进行数据库迁移
文章目录 概要Spring Boot 集成 FlywayFlyway 其他用法bug错误Flyway版本不兼容数据库存在表了Flyway 的校验和(Checksum)不匹配 概要 在 Spring Boot 项目开发中,数据库的变更不可避免。手动执行 SQL 脚本不仅容易出错,也难以维…...
CAS单点登录(第7版)9.属性
如有疑问,请看视频:CAS单点登录(第7版) 属性 属性定义 概述 属性定义 从身份验证或属性存储库源获取和解析 CAS 中属性的定义时,往往使用其名称进行定义和引用,而无需任何其他元数据或修饰。例如&#…...
137,【4】 buuctf web [SCTF2019]Flag Shop
进入靶场 都点击看看 发现点击work会增加¥ 但肯定不能一直点下去 抓包看看 这看起来是一个 JWT(JSON Web Token)字符串。JWT 通常由三部分组成,通过点(.)分隔,分别是头部(Header&…...
P9853 [入门赛 #17] 方程求解
P9853 [入门赛 #17] 方程求解 - 洛谷 题目描述 小A有n个关于x的方程,第i个方程形如aixibici。方程的解x均为正整数,例如下面几个方程都是符合要求的方程: 2x 4 10 -3x 13 10 4x - 8 16 其中,第一组方程的解为x1…...
【网络安全 | 漏洞挖掘】跨子域账户合并导致的账户劫持与删除
未经许可,不得转载。 文章目录 概述正文漏洞成因概述 在对目标系统进行安全测试时,发现其运行着两个独立的域名——一个用于司机用户,一个用于开发者/企业用户。表面上看,这两个域名各自独立管理账户,但测试表明它们在处理电子邮件变更时存在严重的逻辑漏洞。该漏洞允许攻…...
spring集成activiti流程引擎(源码)
前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。 源码获取:本文末个人名片直接获取。 一、项目形式 springbootvueactiviti集成了activiti在线编辑器,流行…...
ROS基本功能
1.Topic话题与Message消息(主要通讯方式) 基本规则 发布消息的步骤 常用工具 话题的订阅 使用launch启动多个节点...
C++基础系列【13】类的成员初始化
博主介绍:程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章,首发gzh,见文末👇…...
Redis 03章——10大数据类型概述
一、which10 (1)一图 (2)提前声明 这里说的数据类型是value的数据类型,key的类型都是字符串 官网:Understand Redis data types | Docs (3)分别是 1.3.1redis字符串࿰…...
Ubuntu 上安装 Elasticsearch 7.6.0
要在 Ubuntu 24.04 上安装 Elasticsearch 7.6.0,可以按照以下步骤进行: 步骤 1: 更新系统依赖 确保系统是最新的,并安装必要的依赖包: sudo apt update sudo apt upgrade -y sudo apt install -y apt-transport-https openjdk-1…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
