抽象工厂模式的C++实现示例

news/2025/3/15 20:14:19/

核心思想

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式,可以创建一系列相关或依赖的对象,而无需指定它们的具体类。抽象工厂模式的核心思想是:
抽象工厂接口:定义一个接口,用于创建一系列相关或依赖的对象。
具体工厂实现:实现抽象工厂接口,创建具体的对象。
抽象产品接口:定义一类产品的接口。
具体产品实现:实现抽象产品接口,创建具体的产品。

解决的问题

产品族创建:当需要创建一系列相关或依赖的对象时,抽象工厂模式可以确保这些对象是兼容的。
客户端与具体类解耦:客户端代码只需要知道抽象工厂和抽象产品接口,而不需要知道具体的实现类,从而降低了耦合度。
易于扩展:当需要增加新的产品族时,只需要增加新的工厂类和产品类,而不需要修改现有代码。

使用场景

产品族创建:当需要创建一系列相关或依赖的对象时,例如不同操作系统的界面组件(按钮、文本框等)。
系统独立性:当需要确保系统与具体类解耦,以便于扩展和维护。
配置文件驱动:当需要通过配置文件或其他方式动态选择产品族时。

优点

产品族一致性:确保创建的对象是兼容的。
客户端与具体类解耦:客户端代码只需要知道抽象接口,而不需要知道具体实现类。
易于扩展:增加新的产品族时,只需要增加新的工厂类和产品类,而不需要修改现有代码。

缺点

复杂性增加:增加了系统的复杂性,需要更多的类和接口。
不易于支持新种类的产品:如果需要增加新的种类的产品,需要修改抽象工厂接口及其所有实现类。

示例代码

#include <iostream>
#include <memory>// 抽象产品A
class AbstractProductA {
public:virtual void use() = 0;virtual ~AbstractProductA() = default;
};// 具体产品A1
class ProductA1 : public AbstractProductA {
public:void use() override {std::cout << "Using ProductA1" << std::endl;}
};// 具体产品A2
class ProductA2 : public AbstractProductA {
public:void use() override {std::cout << "Using ProductA2" << std::endl;}
};// 抽象产品B
class AbstractProductB {
public:virtual void use() = 0;virtual ~AbstractProductB() = default;
};// 具体产品B1
class ProductB1 : public AbstractProductB {
public:void use() override {std::cout << "Using ProductB1" << std::endl;}
};// 具体产品B2
class ProductB2 : public AbstractProductB {
public:void use() override {std::cout << "Using ProductB2" << std::endl;}
};// 抽象工厂
class AbstractFactory {
public:virtual std::unique_ptr<AbstractProductA> createProductA() = 0;virtual std::unique_ptr<AbstractProductB> createProductB() = 0;virtual ~AbstractFactory() = default;
};// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA1>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB1>();}
};// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA2>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB2>();}
};// 客户端代码
void clientCode(std::unique_ptr<AbstractFactory> factory) {auto productA = factory->createProductA();auto productB = factory->createProductB();productA->use();productB->use();
}int main() {std::cout << "Client: Testing client code with the first factory type:" << std::endl;clientCode(std::make_unique<ConcreteFactory1>());std::cout << "Client: Testing client code with the second factory type:" << std::endl;clientCode(std::make_unique<ConcreteFactory2>());return 0;
}

代码解析

抽象产品:AbstractProductA 和 AbstractProductB 是抽象产品接口,定义了产品的行为。
具体产品:ProductA1、ProductA2、ProductB1 和 ProductB2 是具体产品实现类。
抽象工厂:AbstractFactory 是抽象工厂接口,定义了创建产品的方法。
具体工厂:ConcreteFactory1 和 ConcreteFactory2 是具体工厂实现类,分别创建不同的产品族。
客户端代码:clientCode 函数使用抽象工厂接口创建产品,并调用产品的方法。

总结

抽象工厂模式通过提供一种方式来创建一系列相关或依赖的对象,确保这些对象是兼容的,并且将客户端代码与具体类解耦。它适用于需要创建产品族的场景,并且易于扩展和维护。然而,它也会增加系统的复杂性,并且在支持新种类的产品时可能需要修改抽象工厂接口及其所有实现类。


http://www.ppmy.cn/news/1579392.html

相关文章

快速集成1688商品API:10分钟实现跨境选品数据自动化

要快速集成 1688 商品 API 以实现跨境选品数据自动化&#xff0c;可参考以下步骤&#xff1a; 注册并申请 API 权限&#xff1a;注册账号创建应用并申请所需的 API 权限&#xff0c;如商品搜索、筛选、获取详情等相关权限。获取 API Key 和 Secret&#xff1a;在应用管理页面获…

LINUX 指令大全

Linux服务器上有许多常用的命令&#xff0c;可以帮助你管理文件、目录、进程、网络和系统配置等。以下是一些常用的Linux命令&#xff1a; 文件和目录管理 ls&#xff1a;列出当前目录中的文件和子目录 bash lspwd&#xff1a;显示当前工作目录的路径 bash pwdcd&#xff1a;切…

压力测试Monkey命令参数和报告分析!

adb的操作命令格式一般为&#xff1a;adb shell monkey 命令参数 PART 01 常用参数 ⏩ -p <测试的包名列表> 用于约束限制&#xff0c;用此参数指定一个或多个包。指定包之后&#xff0c;Monkey将只允许系统启动指定的APP。如果不指定包&#xff0c;Monkey将允许系统…

Photo Works在线图片编辑器:一键修复老照片,轻松焕新记忆

★【概况介绍】 今天突然收到我的朋友电脑出故障了,截图给我,我一看就知道这个是缺少必要的组件引起的故障。结合这个问题,我来谈谈自己的解决思路和方法,希望能够帮助到大家。帮助大家是我最开心的事情。以前只是帮朋友解决问题,没有记录下来,刚刚接触到这个平台,刚好可…

Flutter:跑马灯公告栏

组件 import dart:async; import package:flutter/material.dart; import package:ducafe_ui_core/ducafe_ui_core.dart;class MarqueeNotice extends StatefulWidget {/// 公告数据列表&#xff0c;每条公告包含title和descfinal List<Map<String, String>> notic…

序列化和反序列化TCP粘包问题

目录 一、什么是序列化和反序列化&#xff1f; 二、利用Jsoncpp实现序列化和反序列化 1.序列化 (1)使用 Json::Value 的 toStyledString 方法 (2)使用 Json::StreamWriterf 方法 (3)使用 Json::FastWriterff 方法 2.反序列化 (1)使用 Json::Reader 方法 三、数据封装&…

机器学习或深度学习中---保存和加载模型的方法

在机器学习或深度学习中&#xff0c;训练好的模型可以通过多种方式保存和加载&#xff0c;以便在后续使用中进行推理&#xff08;预测&#xff09;或进一步训练。以下是常见的保存和加载模型的方法&#xff0c;以 Python 中的常见库&#xff08;如 scikit-learn、TensorFlow、P…

Android 自定义数字键盘实现教程

在 Android 应用中&#xff0c;系统默认的键盘可能无法满足特定需求&#xff08;如仅支持数字输入、自定义布局等&#xff09;。本文将详细介绍如何实现一个自定义数字键盘&#xff0c;并提供完整的代码示例。 实现步骤 1. 创建自定义键盘布局 首先&#xff0c;我们需要定义一…