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

建造者模式(大话设计模式)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()
{// 初始化DirectorDirector 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. 使得建造代码与表示代码分离,隐藏了该产品是如何组装的,多疑若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了

相关文章:

  • 35.简易远程数据框架的实现
  • Leetcode85
  • 软件测试笔记
  • IPv6 中 MAC 33:33 的由来
  • VisualBox 虚拟机 Ubunut 18.04 在大显示器上黑屏的问题
  • 【LinuxC语言】网络编程的本质
  • 动态ARP
  • TCP 协议详解:三次握手与四次挥手
  • 一篇快速教你如何创建专业级数据可视化库
  • 开启数字新纪元:全球首款开源AI女友,你的私人数字伴侣
  • 基于STM32的智能工厂环境监测系统
  • 跌倒识别:守护公共安全的AI技术应用场景-免费API调用
  • Spring Boot事件监听使用指南
  • 【鸿蒙】创建第⼀个鸿蒙项⽬
  • 分布式训练框架
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • ➹使用webpack配置多页面应用(MPA)
  • CentOS从零开始部署Nodejs项目
  • EventListener原理
  • jdbc就是这么简单
  • JS题目及答案整理
  • Kibana配置logstash,报表一体化
  • Leetcode 27 Remove Element
  • vagrant 添加本地 box 安装 laravel homestead
  • Vue.js-Day01
  • WePY 在小程序性能调优上做出的探究
  • 当SetTimeout遇到了字符串
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 深入浏览器事件循环的本质
  • 提醒我喝水chrome插件开发指南
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 进程与线程(三)——进程/线程间通信
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #Z0458. 树的中心2
  • (1)bark-ml
  • (windows2012共享文件夹和防火墙设置
  • (不用互三)AI绘画工具应该如何选择
  • (计算机网络)物理层
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (九)c52学习之旅-定时器
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (十二)Flink Table API
  • (四)模仿学习-完成后台管理页面查询
  • (转)关于pipe()的详细解析
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .net反编译工具
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .php文件都打不开,打不开php文件怎么办
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce