C++ 设计模式:抽象工厂(Abstract Factory)

news2025/1/3 1:31:39

链接:C++ 设计模式
链接:C++ 设计模式 - 工厂方法
链接:C++ 设计模式 - 原型模式
链接:C++ 设计模式 - 建造者模式

抽象工厂(Abstract Factory)是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式通常用于创建一组相关的产品对象,例如不同类型的机器人和它们的配件。

1.问题分析

在某些情况下,我们需要创建一组相关或相互依赖的对象,但我们希望将这些对象的创建过程封装起来,以便于更换具体的产品系列。抽象工厂模式通过定义一组创建对象的接口,使得客户端代码可以独立于具体的产品类。

2.实现步骤

  1. 定义抽象产品接口:定义一组抽象产品接口或抽象类,描述产品的公共接口。
  2. 实现具体产品:实现具体的产品类,这些类实现了抽象产品接口。
  3. 定义抽象工厂接口:定义一个创建一组相关产品对象的接口。
  4. 实现具体工厂:实现具体的工厂类,这些类实现了抽象工厂接口,并负责实例化具体的产品对象。
  5. 创建客户端类:创建一个客户端类,使用抽象工厂接口来创建一组相关的产品对象,并管理它们的行为。
  6. 客户端代码:在main函数中创建具体的工厂对象,并将其传递给客户端类,调用客户端类的方法来管理产品对象。

3.代码示例

3.1.定义抽象产品接口

// 抽象产品A接口
class Robot {
 public:
  virtual ~Robot() = default;
  virtual void performTask() const = 0;
};
// 抽象产品B接口
class Accessory {
 public:
  virtual ~Accessory() = default;
  virtual void use() const = 0;
};

3.2.实现具体产品

// 具体产品A1
class CleaningRobot : public Robot {
 public:
  void performTask() const override { std::cout << "CleaningRobot is cleaning the floor." << std::endl; }
};

// 具体产品B1
class CleaningAccessory : public Accessory {
 public:
  void use() const override { std::cout << "Using CleaningAccessory for cleaning." << std::endl; }
};
// 具体产品A2
class CookingRobot : public Robot {
 public:
  void performTask() const override { std::cout << "CookingRobot is cooking a meal." << std::endl; }
};

// 具体产品B2
class CookingAccessory : public Accessory {
 public:
  void use() const override { std::cout << "Using CookingAccessory for cooking." << std::endl; }
};

3.3.定义抽象工厂接口

class RobotFactory {
 public:
  virtual ~RobotFactory() = default;
  virtual std::unique_ptr<Robot> createRobot() const = 0;
  virtual std::unique_ptr<Accessory> createAccessory() const = 0;
};

3.4.实现具体工厂类

// 具体工厂1
class CleaningRobotFactory : public RobotFactory {
 public:
  std::unique_ptr<Robot> createRobot() const override { return std::make_unique<CleaningRobot>(); }
  std::unique_ptr<Accessory> createAccessory() const override { return std::make_unique<CleaningAccessory>(); }
};
// 具体工厂2
class CookingRobotFactory : public RobotFactory {
 public:
  std::unique_ptr<Robot> createRobot() const override { return std::make_unique<CookingRobot>(); }
  std::unique_ptr<Accessory> createAccessory() const override { return std::make_unique<CookingAccessory>(); }
};

3.5.客户端类

class RobotManager {
 public:
  RobotManager(std::unique_ptr<RobotFactory> factory) : factory_(std::move(factory)) {}

  void manageRobot() const {
    std::unique_ptr<Robot> robot = factory_->createRobot();
    std::unique_ptr<Accessory> accessory = factory_->createAccessory();
    robot->performTask();
    accessory->use();
  }

 private:
  std::unique_ptr<RobotFactory> factory_;
};

3.6.客户端代码

int main() {
  std::unique_ptr<RobotFactory> cleaningFactory = std::make_unique<CleaningRobotFactory>();
  RobotManager cleaningManager(std::move(cleaningFactory));
  cleaningManager.manageRobot();

  std::unique_ptr<RobotFactory> cookingFactory = std::make_unique<CookingRobotFactory>();
  RobotManager cookingManager(std::move(cookingFactory));
  cookingManager.manageRobot();

  return 0;
}

4.总结

抽象工厂与工厂方法的区别:

  • 工厂方法:关注的是单个产品对象的创建。它通过定义一个创建对象的接口,让子类决定实例化哪一个具体类。
  • 抽象工厂:关注的是一组相关或相互依赖的产品对象的创建。它通过定义一个创建一系列相关产品对象的接口,让具体工厂类实现这些接口来创建具体的产品对象。

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

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

相关文章

关于 PCB线路板细节锣槽问题 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144783817 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

SQL创建和操纵表

本文介绍创建、更改和删除表的基本知识。 1. 创建表 SQL 不仅用于表数据操纵&#xff0c;而且还用来执行数据库和表的所有操作&#xff0c;包括表本身的创建和处理。一般有两种创建表的方法&#xff1a; 多数DBMS 都具有交互式创建和管理数据库表的工具&#xff1b;表也可以…

RPA系列-uipath 学习笔记4

使用Uipath 处理hover的问题 备注&#xff1a;使用uipath stversion&#xff1a;2024.10.6,所有学习来源自uipath Academy 首先&#xff0c;打开uipath给我们提供的一个网站 ACME,这个网站呢&#xff0c;需要提前注册一下的哈。 今天呢&#xff0c;就是记录一下&#xff0c;怎…

Unity编译Android apk包进度奇慢或gradle报错的解决方案

最近遇到Unity编译Android apk进度卡在"Calling IPostGenerateGradleAndroidProject callbacks"进度一直不变&#xff0c;如下图&#xff1a; 最后提示编译失败&#xff0c;类似错误如下&#xff1a; Picked up JAVA_TOOL_OPTIONS: -Dfile.encodingUTF-8FAILURE: Bu…

探究音频丢字位置和丢字时间对pesq分数的影响

丢字的本质 丢字的本质是在一段音频中一小段数据变为0 丢字对主观感受的影响 1. 丢字位置 丢字的位置对感知效果有很大影响。如果丢字发生在音频信号的静音部分或低能量部分&#xff0c;感知可能不明显&#xff1b;而如果丢字发生在高能量部分或关键音素上&#xff0c;感知…

CAT3D: Create Anything in 3D with Multi-View Diffusion Models 论文解读

24年5月的论文&#xff0c;上一版就是ReconFusion 目录 一、概述 二、相关工作 1、2D先验 2、相机条件下的2D先验 3、多视角先验 4、视频先验 5、前馈方法 三、Method 1、多视角扩散模型 2、新视角生成 3、3D重建 一、概述 该论文提出一种CAT3D方法&#xff0c;实现…

模型工作流:自动化的模型内部三角面剔除

1. 关于自动减面 1.1 自动减面的重要性及现状 三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产&#xff0c;模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中&#xff0c;模型减面工作是同时关乎质量和性能这两个要素的重要工…

黑马程序员Java笔记整理(day08)

1.代码块 静态代码块 实例代码块 2.内部类 成员内部类 静态内部类 局部内部类 匿名内部类 认识 常见使用形式 应用场景 简化版本 另一个应用场景 3.函数式编程 Lambda 函数简化 方法引用 4.常用API String ArrayList 5.GUI编程 快速认识 事件处理 三种常用写法 第一种 第二…

redis延迟队列

Redis延迟队列 Redis延迟队列是基于Redis构建的消息队列&#xff0c;用来处理需延迟执行的任务。 基本原理 它借助Redis的有序集合&#xff08;Sorted Set&#xff09;数据结构达成目的。会把任务及其执行时间分别当成成员与分值存进有序集合&#xff0c;由于执行时间作为分值&…

爱思唯尔word模板

爱思唯尔word模板 有时候并不一定非得latex https://download.csdn.net/download/qq_38998213/90199214 参考文献书签链接

【JDBC】入门增删改查

JDBC JDBC概述 JDBC&#xff08;Java DataBase Connectivity, java数据库连接&#xff09;是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c;它由一组用Java语言编写的接口和类组成。 XML方式…

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图&#xff0c;后端显示请求成功&#xff0c;前端显示失败 解决方案 1. 后端未配置跨域支持 …

Dify服务器部署教程

Dify的github地址: https://github.com/langgenius/dify 服务器要求&#xff1a;2c4g 1、克隆仓库 可以通过命令或者下载zip解压后上传服务器都行 git clone https://github.com/langgenius/dify.git 2、docker启动 cd dify/dockercp .env.example .envdocker compose up -d…

砝码称重(2021年蓝桥杯)

【问题描述】 你有一架天平和N个砝码&#xff0c;这N个砝码的重量依次是w1,w2,……,wn。&#xff08;1~n为下标&#xff09; 请你计算利用N个砝码一共可以称出多少种不同的重量&#xff1f; 【注意】砝码可以放在天平的两边 【输入格式】 第一行包含一个整数N。 第二行包含N个…

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…

ArcGIS Pro地形图四至角图经纬度标注与格网标注

今天来看看ArcGIS Pro 如何在地形图上设置四至角点的经纬度。方里网标注。如下图的地形图左下角经纬度标注。 如下图方里网的标注 如下为本期要介绍的例图&#xff0c;如下&#xff1a; 图片可点击放大 接下来我们来介绍一下 推荐学习&#xff1a;GIS入门模型构建器Arcpy批量…

win系统B站播放8k视频启用HEVC编码

下载HEVC插件 点击 HEVC Video Extension 2.2.20.0 latest downloads&#xff0c;根据教程下载安装 安装 Random User-Agent 点击 Random User-Agent 安装 配置 Random User-Agent 在youtube中会导致视频无法播放&#xff0c;我选择直接屏蔽了 B站设置

mysql锁机制以及隔离级别下保证并发安全的方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 mysql锁机制以及隔离级别下保证并发安全的方式 多事务并发执行可能出现的问题mysql有那些锁全局锁表级锁行锁 在不同的隔离级别下mysql保证并发安全的方式RU隔离级别RC隔离级…

qwenvl 以及qwenvl 2 模型架构理解

qwenvl 模型理解&#xff1a; 参考资料&#xff1a; https://qwenlm.github.io/zh/blog/qwen2-vl/ https://github.com/QwenLM/Qwen2-VL?tabreadme-ov-file https://qwenlm.github.io/zh/blog/qwen2-vl/ 论文&#xff1a; qwenvl https://arxiv.org/abs/2308.12966 Qwen2-VL …

高效使用AI完成编程项目任务的指南:从需求分析到功能实现

随着人工智能工具的普及&#xff0c;即便是零编程基础或基础薄弱的用户&#xff0c;也可以借助AI完成许多技术任务。然而&#xff0c;要高效地使用AI完成编程任务&#xff0c;关键在于如何清晰表达需求&#xff0c;并逐步引导AI实现目标。 在本文中&#xff0c;我们将通过开发…