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

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

链接: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.kler.cn/a/460086.html

相关文章:

  • js的一些处理
  • ASP.NET CORE 依赖注入的三种方式,分别是什么,使用场景
  • Wireshark和科来网络分析系统
  • 标准库以及HAL库——按键控制LED灯代码
  • 2024年12月 Scratch 图形化(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 面试题:@Transactional 注解在自调用情况下会失效原因
  • pyqt5 设计pdf 和word文件互相转换小程序
  • 二、SQL语言,《数据库系统概念》,原书第7版
  • 【Redis】万字整理 Redis 非关系型数据库的安装与操作
  • Android笔试面试题AI答之Android基础(4)
  • elementui的默认样式修改
  • 备战春招 | 数字IC FPGA笔试题
  • 【从零开始入门unity游戏开发之——C#篇32】C#其他不常用的泛型数据结构类、顺序存储和链式存储
  • Python 爬虫中的反爬策略及详细应对方法
  • 【LLM】Langflow 的简单使用
  • SQL实现新年倒计时功能
  • golang标准库SSH操作示例
  • PHP语言laravel框架中基于Redis的异步队列使用实践与原理
  • 【每日学点鸿蒙知识】中间产物版本号问题、Toast应用外不生效、Dialog键盘问题、WebView cookie、本地缓存
  • 如何判断服务器是否被网络攻击?
  • 【C++】九九乘法表编程题详解与多角度对比分析
  • 整合版canal ha搭建--基于1.1.4版本
  • CSS系列(39)-- Shapes详解
  • 服务器反应慢,秒杀设计
  • 实验七 函数2
  • Flutter-插件 scroll-to-index 实现 listView 滚动到指定索引位置