建造者模式(大话设计模式)C/C++版本

建造者模式

在这里插入图片描述

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15907863.html

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

// Product Class,产品类,由多个部件组成。
class Product
{
private:
    vector<string> parts;

public:
    // 添加产品部件
    void Add(string part)
    {
        parts.push_back(part);
    }
    // 显示所有的产品部件
    void Show()
    {
        std::cout << "产品  创建" << std::endl;
        for_each(parts.cbegin(), parts.cend(), [](const string &s)
                 { cout << s << " "; });
        cout << endl;
    }
};

// Builder,抽象建造者,并声明一个得到产品建造后结果的方法GetResult。
class Builder
{
public:
    virtual ~Builder() = default;
    virtual void BuildPartA() = 0;
    virtual void BuildPartB() = 0;
    virtual Product *GetResult() = 0;
};

// ConcreteBuilder1,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder1 : public Builder
{
private:
    Product *product = new Product;

public:
    void BuildPartA() override
    {
        product->Add("部件A");
    }
    void BuildPartB() override
    {
        product->Add("部件B");
    }
    Product *GetResult() override
    {
        return product;
    }
};

// ConcreteBuilder2,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder2 : public Builder
{
private:
    Product *product = new Product;

public:
    void BuildPartA() override
    {
        product->Add("部件X");
    }
    void BuildPartB() override
    {
        product->Add("部件Y");
    }
    Product *GetResult() override
    {
        return product;
    }
};

class Director //  指挥者类,指挥建造Product的过程(控制构建各部分组件的顺序)。
{
public:
    void Construct(Builder *const b)
    {
        b->BuildPartA();
        b->BuildPartB();
    }
};

int main()
{
    // 用户并不需要知道具体的建造过程,只需指定建造 Product 具体类型。
    Director director;
    Builder *b1 = new ConcreteBuilder1;
    Builder *b2 = new ConcreteBuilder2;

    cout << "用ConcreteBuilder1的方法建造产品: " << endl;
    director.Construct(b1);
    Product *p1 = b1->GetResult();
    p1->Show();
    cout << endl;

    cout << "用ConcreteBuilder2的方法建造产品: " << endl;
    director.Construct(b2);
    Product *p2 = b2->GetResult();
    p2->Show();
    cout << endl;

    delete p2;
    delete p1;
    delete b1;
    delete b2;
    p2 = p1 = nullptr;
    b1 = b2 = nullptr;

    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 产品部件
typedef struct Product
{
    char **parts;
    size_t parts_count;
} Product;

// 构建者接口
typedef struct Builder
{
    void (*build_part_a)(Product *);
    void (*build_part_b)(Product *);
    Product *(*get_result)(void *);
} Builder;

// 具体构建者基类,用于存储产品实例
typedef struct ConcreteBuilder
{
    Product product;
} ConcreteBuilder;

// 导演类
typedef struct Director
{
    void (*construct)(struct Director *, Builder *, void *, Product **);
} Director;

// 初始化产品
void init_product(Product *product)
{
    product->parts = NULL;
    product->parts_count = 0;
}

// 释放产品
void free_product(Product *product)
{
    if (product->parts != NULL)
    {
        int i;
        for (i = 0; i < product->parts_count; ++i)
        {
            free(product->parts[i]);
        }
        free(product->parts);
    }
}

// 添加部件到产品
void add_part(Product *product, const char *part)
{
    product->parts = (char **)realloc(product->parts, sizeof(char *) * (product->parts_count + 1));
    product->parts[product->parts_count++] = strdup(part);
}

// 展示产品部件
void show_product(Product *product)
{
    printf("产品    创建:\n");
    int i;
    for (i = 0; i < product->parts_count; ++i)
    {
        printf("%s ", product->parts[i]);
    }
    printf("\n");
}

// 实现ConcreteBuilder1的构建方法
void build_part_a_concrete_builder1(Product *product)
{
    add_part(product, "部件A");
}

void build_part_b_concrete_builder1(Product *product)
{
    add_part(product, "部件B");
}

// 实现ConcreteBuilder2的构建方法
void build_part_a_concrete_builder2(Product *product)
{
    add_part(product, "部件X");
}

void build_part_b_concrete_builder2(Product *product)
{
    add_part(product, "部件Y");
}

// 获取结果的通用实现,确保安全返回产品实例
Product *get_result_common(void *builder_void_ptr)
{
    ConcreteBuilder *builder = (ConcreteBuilder *)builder_void_ptr;
    return &builder->product;
}

// 导演类构建方法
void construct(Director *director, Builder *builder, void *builder_void_ptr, Product **result)
{
    builder->build_part_a((Product *)builder_void_ptr);
    builder->build_part_b((Product *)builder_void_ptr);
    *result = builder->get_result(builder_void_ptr);
}

int main()
{
    // 初始化Director
    Director director = {.construct = construct};

    // 初始化ConcreteBuilder实例
    ConcreteBuilder builder1;
    init_product(&builder1.product);
    Builder b1 = {
        .build_part_a = build_part_a_concrete_builder1,
        .build_part_b = build_part_b_concrete_builder1,
        .get_result = get_result_common};

    ConcreteBuilder builder2;
    init_product(&builder2.product);
    Builder b2 = {
        .build_part_a = build_part_a_concrete_builder2,
        .build_part_b = build_part_b_concrete_builder2,
        .get_result = get_result_common};

    Product *p1 = NULL;
    Product *p2 = NULL;

    printf("使用ConcreteBuilder1的方法建造产品: \n");
    director.construct(&director, &b1, &builder1, &p1);
    show_product(p1);
    puts("");

    printf("使用ConcreteBuilder2的方法建造产品: \n");
    director.construct(&director, &b2, &builder2, &p2);
    show_product(p2);
    puts("");

    free_product(p1);
    free_product(p2);

    return 0;
}

总结

  1. 创建者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式;
  2. 使得建造代码与表示代码分离,隐藏了该产品是如何组装的,多疑若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++获取Windows系统的各个磁盘盘符及容量信息(附源码)

目录 1、调用GetLogicalDrives接口获取逻辑磁盘个数 2、调用GetLogicalDriveStrings接口获取磁盘盘符列表字串 3、从磁盘列表字串中解析出每个磁盘盘符并获取对应的磁盘类型 4、调用GetDiskFreeSpaceEx接口获取磁盘的容量信息 5、完整代码展示 VC++常用功能开发汇总(专栏…

DearLicy主题 | 小众化小清新风格的博客主题源码 | Typecho主题模版

DearLicy主题&#xff0c;一款小众化小清新风格的博客主题 主题支持Typecho所支持的所有版本PHP 简约、小众、优雅 安装教程 1.将主题上传至/usr/themes/文件夹下解压 2.后台进行启用 3.访问前台查看效果 源码下载&#xff1a;https://download.csdn.net/download/m0_6604…

⌈ 传知代码 ⌋ 2 行代码搞定火灾检测

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

C学习自学笔记

C学习笔记 0>C语言概述 为什么学习C语言 1&#xff09;C的起源和发展------了解即可 B语言、C语言、C语言的产生地&#xff1a;都出自 美国贝尔实验室 2&#xff09;C的特点 优点&#xff1a;代码量小、速度快、功能强大 缺点&#xff1a;危险性高、开发周期长、可移植性…

德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第八周) - 现代大语言模型

现代大语言模型 1. GPT-32. 上下文学习 2.1. 零样本提示2.2. 少样本提示2.3. 归纳头 3. 对齐 3.1. 指令微调3.2. 基于人类反馈的强化学习3.3. 事实与幻觉 1. GPT-3 GPT系列论文 GPT-1(2018): Improving Language Understanding by Generative Pre-TrainingGPT-2(2019): Lang…

Cheat Engine CE v7.5 安装教程(专注于游戏的修改器)

前言 Cheat Engine是一款专注于游戏的修改器。它可以用来扫描游戏中的内存&#xff0c;并允许修改它们。它还附带了调试器、反汇编器、汇编器、变速器、作弊器生成、Direct3D操作工具、系统检查工具等。 一、下载地址 下载链接&#xff1a;http://dygod/source 点击搜索&…

Ubuntu 22.04 解决 firefox 中文界面乱码

问题复现 在为Ubuntu 22.04 Server安装完整的GNOME 42.01桌面后&#xff0c;将桌面语言设置为中文时&#xff0c;打开Firefox可能会出现中文乱码的问题。经过网上调查发现&#xff0c;这个问题是由Snap软件包引起的。 解决方案 为了避免在Ubuntu 22.04中文模式下的乱码问题…

【设计文档】软件项目详细设计说明书案例(套用模板Word)

1引言 1.1编写目的 1.2项目背景 1.3参考材料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4设计目标 2.5.1总体原则 2.5.2实用性和先进性 2.5.3标准化、开放性、兼容性 2.5.4高可靠性、稳定性 2.5.5易用性 2.5.6灵活性和可扩展性 2.5.7经济性和投资保护 3系统…

redis源码编译安装

源码下载地址http://download.redis.io/releases/ 1 环境准备 安装编译环境 sudo yum install gcc -y gcc -v 查看版本 sudo yum -y install centos-release-scl sudo yum -y install devtoolset-10-gcc devtoolset-10-gcc-c devtoolset-10-binutils scl enable devtool…

Linux rm命令由于要删的文件太多报-bash: /usr/bin/rm:参数列表过长,无法删除的解决办法

银河麒麟系统&#xff0c;在使用rm命令删除文件时报了如下错误&#xff0c;删不掉&#xff1a; 查了一下&#xff0c;原因就是要删除的文件太多了&#xff0c;例如我当前要删的文件共有这么多&#xff1a; 查到了解决办法&#xff0c;记录在此。需要使用xargs命令来解决参数列表…

Mybatis用Map接收返回值可能出现的问题

先看一个示例 明明定义了Map<String,String> 实际内部存放的是Integer resultType是Map 也就是说Mybatis是通过反射将类型放进去的 躲过了编辑器检查 但是这样取值时候就会报类型转换错误 解决方式 resultMap 另外一种方式 用Number Integer和Double的父类 Ma…

【Qt】QT textBrowser 设置字体颜色和大小

1. 效果 2. 代码 {ui->methodText->append("<font size9 colorgreen> dddddddddd </font>");ui->methodText->append("<font size9 colorred> vvvvvvvvvv </font>"); }

正解 x86 Linux 内存管理

1&#xff0c;机器解析的思路 发现网络上大量的教程&#xff0c;多是以讹传讹地讲解 Linux 内存管理&#xff1b; 都是在讲&#xff1a; 逻辑地址 -> 线性地址 -> 物理地址 这个转换关系是怎么发生的。 上面这个过程确实是程序运行时地址的翻译顺序&#xff1b; …

【C++ | 静态成员】类的 静态(static)数据成员、静态(static)成员函数 详解及例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-16 0…

文献学习——PWM - PFM模式无缝转换的PFC变换器统一控制

PWM - PFM模式无缝转换的PFC变换器统一控制 摘要&#xff1a;断续导通模式通常应用在升压功率因数校正转换器中。这篇文章提出了一种基于虚拟阻抗原理的实现脉冲宽度调制控制和脉冲频率调制控制的统一控制方法。控制模式可以简单的通过只调整一个控制参数来改变。因此&#xf…

现代信号处理14_基于蒙特卡洛的信号处理(CSDN_20240616)

Monte Carlo/Simulation方法 在统计上&#xff0c;样本数量是一个很重要的问题&#xff0c;在处理问题&#xff08;如计算样本均值&#xff09;的过程中&#xff0c;样本数量越多越好。但是在实际中&#xff0c;样本往往是稀缺的&#xff0c;获取数据就要付出代价。在贝叶斯理论…

GPTZero:引领AI内容检测

随着人工智能技术的飞速发展,AI生成内容(AIGC)正在迅速改变我们获取和消费信息的方式。然而,AIGC的激增也带来了一系列挑战,尤其是在内容真实性和版权方面。正是在这样的背景下,一家由00后团队创立的公司——GPTZero,以其独特的AI检测工具,迅速崛起为行业的领军者。 一…

回归预测 | Matlab实现GWO-ESN基于灰狼算法优化回声状态网络的多输入单输出回归预测

回归预测 | Matlab实现GWO-ESN基于灰狼算法优化回声状态网络的多输入单输出回归预测 目录 回归预测 | Matlab实现GWO-ESN基于灰狼算法优化回声状态网络的多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-ESN基于灰狼算法优化回声状态…

Linux 文件的权限信息解读 chmod修改权限 数字序号表示权限

ls -l #列出当前文件 显示详细信息 drwxr-xr-x. 2 dpc test 6 Jun 15 07:45 test.txt共分为三部分 drwxr-xr-x.&#xff1a;表示文件和文件夹的权限信息dpc &#xff1a;文件&#xff0c;文件夹所属的用户test &#xff1a; 文件和文件夹所属的用户组 drwxr-xr-x 解读 d表示为…

Python自动化办公(一) —— 根据PDF文件批量创建Word文档

Python自动化办公&#xff08;一&#xff09; —— 根据PDF文件批量创建Word文档 在日常办公中&#xff0c;我们经常需要根据现有的PDF文件批量创建Word文档。手动操作不仅费时费力&#xff0c;而且容易出错。幸运的是&#xff0c;使用Python可以轻松实现这个过程。本文将介绍如…