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

C++实现设计模式---抽象工厂模式 (Abstract Factory)

抽象工厂模式 (Abstract Factory)

抽象工厂模式 是一种创建型设计模式,提供一个接口,用于创建一组相关或互相依赖的对象,而无需指定它们的具体类。


意图

  • 提供一个创建一组相关对象的接口,而无需指定它们的具体类。
  • 解决产品对象之间的相互依赖问题,使得一组对象能协同工作。

使用场景

  1. 需要创建一组相关对象
    • 如 GUI 程序中,窗口、按钮、菜单等需要统一的外观风格。
  2. 需要保证对象之间的兼容性
    • 如游戏开发中,不同种族的士兵和建筑需要互相匹配。
  3. 需要隐藏具体实现
    • 客户端代码只依赖于产品接口,具体实现被封装。

参与者角色

  1. 抽象工厂 (Abstract Factory)
    • 声明一组用于创建相关对象的接口。
  2. 具体工厂 (Concrete Factory)
    • 实现抽象工厂的接口,创建具体的产品。
  3. 抽象产品 (Abstract Product)
    • 定义所有产品的公共接口。
  4. 具体产品 (Concrete Product)
    • 实现抽象产品的接口,为具体工厂生产的对象。

示例代码

以下示例展示了如何使用抽象工厂模式为不同操作系统创建相关的 GUI 组件(按钮和窗口)。

#include <iostream>
#include <memory>// 抽象产品 A: 按钮
class Button {
public:virtual void render() const = 0;virtual ~Button() {}
};// 具体产品 A1: Windows 按钮
class WindowsButton : public Button {
public:void render() const override {std::cout << "Rendering Windows Button" << std::endl;}
};// 具体产品 A2: Mac 按钮
class MacButton : public Button {
public:void render() const override {std::cout << "Rendering Mac Button" << std::endl;}
};// 抽象产品 B: 窗口
class Window {
public:virtual void render() const = 0;virtual ~Window() {}
};// 具体产品 B1: Windows 窗口
class WindowsWindow : public Window {
public:void render() const override {std::cout << "Rendering Windows Window" << std::endl;}
};// 具体产品 B2: Mac 窗口
class MacWindow : public Window {
public:void render() const override {std::cout << "Rendering Mac Window" << std::endl;}
};// 抽象工厂
class GUIFactory {
public:virtual std::unique_ptr<Button> createButton() const = 0;virtual std::unique_ptr<Window> createWindow() const = 0;virtual ~GUIFactory() {}
};// 具体工厂 1: Windows 工厂
class WindowsFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() const override {return std::make_unique<WindowsButton>();}std::unique_ptr<Window> createWindow() const override {return std::make_unique<WindowsWindow>();}
};// 具体工厂 2: Mac 工厂
class MacFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() const override {return std::make_unique<MacButton>();}std::unique_ptr<Window> createWindow() const override {return std::make_unique<MacWindow>();}
};// 主函数
int main() {// 选择具体工厂std::unique_ptr<GUIFactory> factory = std::make_unique<WindowsFactory>();// 使用工厂创建产品auto button = factory->createButton();auto window = factory->createWindow();button->render(); // 输出:Rendering Windows Buttonwindow->render(); // 输出:Rendering Windows Window// 切换到另一种具体工厂factory = std::make_unique<MacFactory>();button = factory->createButton();window = factory->createWindow();button->render(); // 输出:Rendering Mac Buttonwindow->render(); // 输出:Rendering Mac Windowreturn 0;
}

代码解析

1. 抽象产品类

定义了产品的公共接口,确保产品类型的一致性:

class Button {
public:virtual void render() const = 0;virtual ~Button() {}
};

2. 具体产品类

实现了抽象产品接口,并提供具体功能:

class WindowsButton : public Button {
public:void render() const override {std::cout << "Rendering Windows Button" << std::endl;}
};

3. 抽象工厂

定义了创建一组相关产品的接口:

class GUIFactory {
public:virtual std::unique_ptr<Button> createButton() const = 0;virtual std::unique_ptr<Window> createWindow() const = 0;virtual ~GUIFactory() {}
};

4. 具体工厂

实现了抽象工厂接口,负责生产具体的产品:

class WindowsFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() const override {return std::make_unique<WindowsButton>();}std::unique_ptr<Window> createWindow() const override {return std::make_unique<WindowsWindow>();}
};

5. 主函数

客户端代码通过工厂接口创建产品,无需知道具体产品的实现:

std::unique_ptr<GUIFactory> factory = std::make_unique<WindowsFactory>();
auto button = factory->createButton();
auto window = factory->createWindow();
button->render();
window->render();

优缺点

优点

  1. 解耦:客户端代码只依赖抽象工厂和抽象产品,与具体实现无关。
  2. 保证产品一致性:抽象工厂确保一组对象是兼容的。
  3. 扩展性强:可以通过新增具体工厂扩展系统。

缺点

  1. 增加复杂性:每增加一组产品需要新增抽象类和具体类。
  2. 灵活性受限:对现有产品结构的修改可能需要更新所有工厂。

适用场景

  • 跨平台开发:如为不同操作系统设计统一的 GUI。
  • 产品族设计:如游戏中不同种族的士兵和建筑需要互相匹配。
  • 动态扩展产品族:如增加新的平台支持。

改进与扩展

  1. 结合配置文件
    动态选择具体工厂,根据运行时条件决定产品族的创建:

    std::unique_ptr<GUIFactory> factory;
    if (platform == "Windows") {factory = std::make_unique<WindowsFactory>();
    } else {factory = std::make_unique<MacFactory>();
    }
    
  2. 引入依赖注入框架
    通过依赖注入简化工厂选择的逻辑,使得代码更易于维护和测试。


总结

抽象工厂模式通过提供一个接口,用于创建一组相关对象,实现了创建逻辑的集中化和产品族之间的兼容性。
它适用于需要跨平台开发或产品族设计的场景。

相关文章:

C++实现设计模式---抽象工厂模式 (Abstract Factory)

抽象工厂模式 (Abstract Factory) 抽象工厂模式 是一种创建型设计模式&#xff0c;提供一个接口&#xff0c;用于创建一组相关或互相依赖的对象&#xff0c;而无需指定它们的具体类。 意图 提供一个创建一组相关对象的接口&#xff0c;而无需指定它们的具体类。解决产品对象之…...

K8S开启/关闭审计日志

K8S默认禁用审计 开启/关闭 k8s 审计日志 默认 Kubernetes 集群不会输出审计日志信息。通过以下配置&#xff0c;可以开启 Kubernetes 的审计日志功能。 准备审计日志的 Policy 文件配置 API 服务器&#xff0c;开启审计日志重启并验证 准备审计日志 Policy 文件 apiVersio…...

css盒子水平垂直居中

目录 1采用flex弹性布局&#xff1a; 2子绝父相margin&#xff1a;负值&#xff1a; 3.子绝父相margin:auto&#xff1a; 4子绝父相transform&#xff1a; 5通过伪元素 6table布局 7grid弹性布局 文字 水平垂直居中链接&#xff1a;文字水平垂直居中-CSDN博客 以下为盒子…...

px、em 和 rem 的区别:深入理解 CSS 中的单位

文章目录 前言一、px - 像素 (Pixel)二、em - 相对父元素字体大小 (Ems)三、rem - 相对于根元素字体大小 (Root Ems)四、综合比较结语 前言 在CSS中&#xff0c;px、em和rem是三种用于定义尺寸&#xff08;如宽度、高度、边距、填充等&#xff09;的长度单位。它们各自有不同的…...

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的扩大&#xff0c;粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查&#xff0c;效率低下且容易出现疏漏&#xff0c;无法及时发现潜在问题&#xff0c;可能导致粮食受潮、霉变…...

【后端面试总结】tls中.crt和.key的关系

tls中.crt和.key的关系 引言 在现代网络通信中&#xff0c;特别是基于SSL/TLS协议的加密通信中&#xff0c;.crt和.key文件扮演着至关重要的角色。这两个文件分别代表了数字证书和私钥&#xff0c;是确保通信双方身份认证和数据传输安全性的基石。本文旨在深入探讨TLS中.crt和…...

日拱一卒(20)——leetcode学习记录:大小为 K 且平均值大于等于阈值的子数组数目

一、题目 给定数组&#xff0c;统计数组中长度为k的子数组且该子数组的平均值大于threshold的数量 二、思路 滑动窗思路&#xff0c;计算长度为k的滑动窗的平均值&#xff0c;关键点在于&#xff0c;每滑动一次&#xff0c;只需要去掉头增加尾&#xff0c;而不需要重新全部计…...

项目练习:若依管理系统字典功能-Vue前端部分

文章目录 一、情景说明二、若依Vue相关代码及配置1、utils代码2、components组件3、api接口代码4、Vuex配置5、main.js配置 三、使用方法1、html部分2、js部分 一、情景说明 我们在做web系统的时候&#xff0c;肯定会遇到一些常量选择场景。 比如&#xff0c;性别&#xff1a;…...

apache-skywalking-apm-10.1.0使用

apache-skywalking-apm-10.1.0使用 本文主要介绍如何使用apache-skywalking-apm-10.1.0&#xff0c;同时配合elasticsearch-8.17.0-windows-x86_64来作为存储 es持久化数据使用。 步骤如下&#xff1a; 一、下载elasticsearch-8.17.0-windows-x86_64 1、下载ES(elasticsear…...

计算机视觉算法实战——视频分析(Video Analysis)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​ ​​​​​​​​​​​​ ​​​​​ 视频分析是计算机视觉中的一个重要领域&#xff0c;旨在从视频数据中提取有用的信息&…...

全网首发:编译libssh,产生类似undefined reference to `EVP_aes_256_ctr@OPENSSL_1_1_0‘的大量错误

具体错误 前面和后面的&#xff1a; /opt/linux/x86-arm/aarch64-mix210-linux/host_bin/../lib/gcc/aarch64-linux-gnu/7.3.0/../../../../aarch64-linux-gnu/bin/ld: warning: libcrypto.so.1.1, needed by ../lib/libssh.so.4.10.1, not found (try using -rpath or -rpat…...

用python实战excel和word自动化

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 python实现excel和word自动化--批量处理 前言--需求快要期末了需要&#xff0c;提交一个年级的学生成绩数据&#xff0c;也就是几百份。当前我们收集了一份excel表格&#xf…...

【云计算】OpenStack云计算平台

OpenStack云计算平台框架搭建 1.先换源 先换成阿里源: curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 2.安装框架 yum -y install centos-release-openstack-train 3.安装客户端 yum -y install python-openstackclient 但…...

好用的php商城源码有哪些?

选择一个优秀的商城工具&#xff0c;能更好地帮助大家建立一个好用的商城系统。目前比较流行的都是开源PHP商城系统&#xff0c;那么现实中都有哪些好用的PHP商城源码值得推荐呢&#xff1f;下面就带大家一起来了解一下。 1.TigShop 【推荐指数】&#xff1a;★★★★★☆ 【推…...

docker安装Nginx UI

开源地址&#xff1a;nginx-ui/README-zh_CN.md at dev 0xJacky/nginx-ui GitHub docker run -dit \ --namenginx-ui \ --restartalways \ -e TZAsia/Shanghai \ -v /Users/xiaoping/docker/appdata/nginx:/etc/nginx \ -v /Users/xiaoping/docker/appdata/nginx-ui:/etc/ng…...

为深度学习创建PyTorch张量 - 最佳选项

为深度学习创建PyTorch张量 - 最佳选项 正如我们所看到的&#xff0c;PyTorch张量是torch.Tensor​ PyTorch类的实例。张量的抽象概念与PyTorch张量之间的区别在于&#xff0c;PyTorch张量为我们提供了一个可以在代码中操作的具体实现。 在上一篇文章中&#xff0c;我们看到了…...

详解数据增强中的平移shft操作

Shift 平移是指在数据增强&#xff08;data augmentation&#xff09;过程中&#xff0c;通过对输入图像或目标进行位置偏移&#xff08;平移&#xff09;&#xff0c;让目标在图像中呈现出不同的位置。Shift 平移的目的是增加训练数据的多样性&#xff0c;从而提高模型对目标在…...

CCLINKIE转ModbusTCP网关,助机器人“掀起”工业智能的“惊涛骇浪”

以下是一个稳联技术CCLINKIE转ModbusTCP网关&#xff08;WL-CCL-MTCP&#xff09;连接三菱PLC与机器人的配置案例&#xff1a;设备与软件准备设备&#xff1a;稳联技术WL-CCL-MTCP网关、三菱FX5UPLC、支持ModbusTCP协议的机器人、网线等。 稳联技术ModbusTCP转CCLINKIE网关&…...

类型安全与代码复用的C# 泛型

一、引言&#xff1a;泛型 ——C# 编程的神奇钥匙 在 C# 编程的广袤天地里&#xff0c;泛型宛如一把神奇钥匙&#xff0c;能够开启高效、灵活且安全的代码之门&#x1f6aa;。 想象一下&#xff0c;你是一位经验丰富的建筑师&#xff0c;要建造各种各样的房子&#x1f3e0;。…...

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...