c++ 建造者模式

news2024/9/27 9:24:24

文章目录

  • 建造者模式
    • 为什么使用建造者模式
    • 建造者模式实现步骤
    • 实现示例
    • 建造者模式优缺点

建造者模式

建造者模式(Builder Pattern)是面向对象设计模式中的一种,主要用于创建复杂对象。这种模式将对象的构建过程与其表示分离,允许用户通过相同的构建过程创建不同的表示。以下是建造者模式的一些关键概念:

  • 产品(Product):
    这是最终要创建的复杂对象。产品可能由多个组成部分构成,这些部分可以有不同的表现形式。
  • 抽象建造者(Builder):
    定义了一个用于创建复杂对象的接口,但并不涉及具体的部件和它们的装配方式。它通常包含一系列用于构建产品各个部分的方法。
  • 具体建造者(Concrete Builder):
    实现了抽象建造者接口,负责构建并装配各个部分。具体建造者类通常包含了构建产品各个部分的业务逻辑。
  • 指挥者(Director):
    使用建造者对象中的方法来创建产品对象。指挥者不关心具体产品是如何被构建的,它只负责指导建造者去构建产品。有时,指挥者的职责可以内嵌到客户端代码中。
    在这里插入图片描述

为什么使用建造者模式

主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
建造者模式(Builder Pattern)主要在以下几种情况下使用,以解决特定的设计问题:

  • 对象构造复杂:
    当一个对象的构造过程复杂,涉及到很多不同的选项或配置,而且这些选项之间可能存在依赖关系时,使用建造者模式可以将构造过程分解为一系列小步骤,每个步骤负责设置对象的一部分属性。这使得构造过程更清晰,避免了构造函数中出现大量参数的情况,也使得对象的构造更为灵活。
  • 对象具有多种变体:
    如果一个对象可能有多种不同的配置或表示形式,而这些配置或表示在构造时就已经确定,那么可以使用建造者模式来创建这些变体。通过不同的具体建造者,可以构造出不同配置的对象实例。
  • 构造过程独立于部件:
    建造者模式使构建过程和产品对象的表示相分离,这意味着即使构建过程改变,也不影响产品对象的表示,反之亦然。这有助于维护代码的稳定性和可扩展性。
  • 控制构建过程的顺序:
    某些情况下,对象的构建顺序很重要,而这个顺序可能会随时间变化。建造者模式通过将构建过程委托给Director(指挥者)类来管理,可以很容易地调整构建顺序,而无需修改建造者本身。
  • 减少重复代码:
    当构建相似但不完全相同的产品对象时,建造者模式可以减少重复代码。不同的建造者可以共享相同的构建逻辑,只是在某些步骤上有所不同。
  • 易于扩展和维护:
    如果未来需要增加新的产品特性,只需添加新的建造者类,而无需修改现有的建造者或产品类。这使得系统更容易适应需求变化。

例如,在软件开发中,创建一个复杂的数据库连接工厂可能需要指定不同的数据库类型、驱动程序、连接字符串、身份验证信息等。使用建造者模式,你可以逐步设定这些参数,同时保持代码的清晰和可维护性。

建造者模式实现步骤

1.提供抽象建造者类: 为创建产品各个部分,统一抽象接口

2.提供具体建造者类:具体实现抽象建造者各个部件的接口

3.提供多个具体产品类:具体的创建产品的各个部分

4.提供一个指挥类:负责安排和调度复杂对象的各个建造过程

实现示例

//电脑组装:显示器、鼠标、键盘、主机(主机又包括cpu、显卡、主板等)
//1.找到店铺老板告诉需求
//2.客服安排技术员工组装
//3.产品组装完成
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//电脑组装:显示器、鼠标、键盘、主机(主机又包括cpu、显卡、主板等)
//1.找到店铺老板告诉需求
//2.客服安排技术员工组装
//3.产品组装完成
//抽象产品类
class AbstractProduct 
{
public:
	virtual void SetDisplayer(string displayer) = 0;
	virtual void SetMouse(string mouse) = 0;
	virtual void SetKeyBoard(string keyBoard) = 0;
	virtual void SetHost(string host) = 0;
	virtual void Show() = 0;
};
//具体产品类
class Computer :public AbstractProduct
{
	void SetDisplayer(string displayer)
	{
		m_list.push_back(displayer);
	}
	void SetMouse(string mouse)
	{
		m_list.push_back(mouse);
	}
	void SetKeyBoard(string keyBoard) 
	{
		m_list.push_back(keyBoard);
	}
	void SetHost(string host) 
	{
		m_list.push_back(host);
	}
	void Show() 
	{
		cout << "电脑配置结果:" << endl;
		for (auto v : m_list) 
		{
			cout << v << endl;
		}
	}
	vector<string> m_list;
};
//抽象建造者类
class AbstractBuilder 
{
public:
	AbstractBuilder():product(new Computer) {}
	//抽象构造过程
	virtual void BuildDisplayer(string displayer) = 0;
	virtual void BuildMouse(string mouse) = 0;
	virtual void BuildKeyBoard(string keyBoard) = 0;
	virtual void BuildHost(string host) = 0;
	AbstractProduct* Getproduct() 
	{
		return product;
	}
protected:
	AbstractProduct* product;
};
//具体的建造者类--->组装电脑的技术员
class ConcreteBuilder :public AbstractBuilder 
{
public:
	void BuildDisplayer(string displayer) 
	{
		product->SetDisplayer(displayer);
	}
	void BuildMouse(string mouse) 
	{
		product->SetMouse(mouse);
	}
	void BuildKeyBoard(string keyBoard) 
	{
		product->SetKeyBoard(keyBoard);
	}
	void BuildHost(string host) 
	{
		product->SetHost(host);
	}
};
//指挥者类
class Director 
{
public:
	Director(AbstractBuilder* pBuilder) :pBuilder(pBuilder) {}
	AbstractProduct* createProduct(string displayer, string mouse, string keyBoard, string host) 
	{
		pBuilder->BuildDisplayer(displayer);
		pBuilder->BuildMouse(mouse);
		pBuilder->BuildKeyBoard(keyBoard);
		pBuilder->BuildHost(host);
		return pBuilder->Getproduct();
	}
private:
	AbstractBuilder* pBuilder;
};


int main() 
{
	AbstractBuilder* pB = new ConcreteBuilder;
	Director* pD = new Director(pB);
	AbstractProduct* computer = pD->createProduct("华为显示器", "牧马人鼠标", "雷蛇键盘", "外星人");
	computer->Show();
	return 0;
}

建造者模式优缺点

优点

  • 封装性好,构建和表示分离

  • 扩展性好,各个具体的建造者相互独立,有利于系统的解耦

  • 控制细节风险,客户端无需详知细节,建造者细化创建过程

缺点

  • 产品的组成部分必须相同,这限制了其使用范围

  • 产品内部发生变化,建造者需同步修改,后期维护成本较大

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt+ESP32+SQLite 智能大棚

环境简介 硬件环境 ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器 基本工作流程 上位机先运行&#xff0c;下位机启动后尝试连接上位机连接成功后定时上报传感器数据到上位机&#xff0c;上位机将信息进行处理展示判断下位机传感器数据&#xff0c;如果超过设置的阈值&a…

电商出海第一步,云手机或成重要因素

电商出海第一步并非易事&#xff0c;挑战和机遇并存&#xff0c;出海企业或个人或将借助云手机从而达成商业部署全球化的目的&#xff1b; 下面我们从网络稳定、数据安全、成本、以及多平台适配方面来看&#xff0c;究竟为什么说云手机会成为出海的重要因素&#xff1b; 首先…

图谱动态240709

本期将分享近期全球知识图谱相关 行业动态、会议资讯、论文推荐 —--| 行业动态 |--— 微软开源GraphRAG 7月2日&#xff0c;微软开源了GraphRAG&#xff0c;一种基于图的检索增强生成(RAG) 方法&#xff0c;可以对私有或以前未见过的数据集进行问答&#xff08;开源地址&…

ENSP防火墙

实验拓扑图 需求&#xff1a; ENSP的配置&#xff1a; 防火墙&#xff1a; 交换机&#xff1a; 华为防火墙的配置&#xff1a; 接口配置&#xff1a; 安全区域&#xff1a; 安全策略&#xff1a; 办公区访问DMZ&#xff1a; 生产区访问DMZ&#xff1a; 游客区只能访问门户网…

USB转RS485+RS232+TTL串口电路

USB转RS485RS232TTL电路 USB转RS485RS232TTL电路如下图所示&#xff0c;可实现USB转RS485RS232TTL串口&#xff0c;一个电路模块即可实现电路调试过程中用到常用接口。 电路模块上留有2.54MM单排针接口和接线端子两种接线方式&#xff0c;可接线和跳线。电路模块同时有5V和3.3V…

Vulkan入门系列0- Vulkan与OpenGL的区别

一:概述 Vulkan 是新一代图形和计算API,是由科纳斯组织(Khronos Group)维护的一套跨平台的、开放标准的、现代GPU 的编程接口,它仅仅是规定了一套编程接口,并没有接口的具体实现,实现是由硬件厂商适配实现的,市面上像NVIDIA、AMD和Intel等国际大厂基本提供了完整的…

C++ enum class转常量

当使用 enum class 时&#xff0c;它具有更强的类型安全性和隔离性&#xff0c;因此需要显式转换才能访问其底层整数值。 std::underlying_type_t 是一个类型别名&#xff0c;它返回枚举类型的底层类型。 to_underlying 函数提供了一种方便的方式来执行这种转换&#xff0c;特别…

vb.netcad二开自学笔记8:界面之任务窗格

使用net可以创建一个类似属性面板的自定义的任务窗格&#xff0c;从而实现应用程序更丰富的人机交互。 1、添加一个自定义控件 2、在前面创建的代码框架内增加一个命令函数ShowMyPalette Imports System.Windows.Media.Imaging Imports Autodesk.AutoCAD.ApplicationServices …

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…

5G中的RedCap

5G中的RedCap&#xff1a;降低能力的重要性和实现方式 随着5G技术的推广和普及&#xff0c;设备和终端的多样化使得网络能力的管理变得更加复杂和关键。RedCap&#xff08;Reduced Capability&#xff09;作为一个重要的概念&#xff0c;旨在解决设备能力差异对网络服务和用户…

基于PID控制器的双容控制系统matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1PID控制器的基本原理 4.2双容水箱系统的数学模型 5.完整工程文件 1.课题概述 基于PID控制器的双容控制系统matlab仿真&#xff0c;仿真输出PID控制下的水位和流量两个指标。 2.系统仿真结果 &…

部署YUM仓库及NFS共享功能

目录 一、YUM仓库服务 1、YUM仓库概述 2、准备安装源 2.1、软件仓库的提供方式 2.2、 RPM软件包的来源 3、YUM主配置文件 4、软件卸载 5、YUM源的提供方式 5.1、配置本地YUM源仓库 5.2、配置ftp源 5.2.1、服务端配置 5.2.2、客户端配置 二、NFS共享存储 1、NFS基…

Element UI 添加自定义图标

Element UI 自带的默认图标 随着项目的越来越大&#xff0c;图标总是不够用&#xff0c;接下来就给大家说明下如何添加自定义图标 首页给大家介绍一个图标网站&#xff1a;iconfont-阿里巴巴矢量图标库 网站上有很多设计好的图标&#xff0c;基本都有你想要的了&#xff0c…

【RHCE】系统服务综合实验

一、实验内容 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在 /nfs/rhce 目录 5、该目录由 node02…

【机器学习实战】Datawhale夏令营2:音视频攻防(deepfake)Baseline句解

# Datawhale # AI夏令营 # 夏令营 文章目录 1. 赛题简要介绍2. 赛题数据集3. 评价指标4. Baseline整体4.1 计算样本数4.2 创建video对象4.3 下载需要的库&&补充知识4.4 设置pytorch随机种子&&CUDNN配置4.5 音视频预处理4.6 创建训练数据文件夹4.7 生成梅尔频谱…

Windows下查看某个端口被某个应用占用

1、打开命令窗口(以管理员身份运行) ​​​​​​​​​​ 2、查找所有运行的端口 输入所有命令&#xff1a;当前命令可以查看当前电脑的全部端口使用情况 netstat -ano3、查看被占用端口对应的 PID&#xff08;这里以8000端口为例&#xff09; netstat -ano|findstr &qu…

Zynq系列FPGA实现SDI视频编解码+多路视频融合叠加,基于GTX高速接口,提供2套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案多路视频融合叠加应用 3、详细设计方案设计原理框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBVDMA图像缓存HLS多路视频融合叠加HDMI视频输出架构SDI视频输出架构之-…

模型加载20G以上的超大语料的解决方案

背景&#xff1a; 在做机器翻译的时候&#xff0c;我们的单边语料大约20G大小的纯文本语料&#xff0c;在DataLoader加载的时候不可能一次性加载进来&#xff0c;所以就有了这个超大语料的加载问题。 解决方案&#xff1a; data_dealing.py: import os import sysroot_dir …