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

【C++ | 设计模式】抽象工厂模式的详解与实现

1. 概念

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。它允许客户端代码通过工厂接口来创建一组对象,而无需了解它们的具体实现细节。

2. 结构

抽象工厂模式通常包括以下几个角色:

  1. AbstractFactory: 抽象工厂接口,声明了创建一系列产品的方法。

  2. ConcreteFactory: 具体工厂,实现 AbstractFactory 接口,创建具体的产品对象。

  3. AbstractProduct: 抽象产品接口,为每种产品定义一个接口。

  4. ConcreteProduct: 具体产品,实现 AbstractProduct 接口,提供产品的具体实现。

  5. Client: 使用抽象工厂和抽象产品接口来实现业务逻辑,无需了解具体的产品类。

3. UML 结构图:

4. 优缺点

优点:

  1. 解耦: 客户端与具体的产品类解耦,客户端只需依赖于抽象接口。
  2. 扩展性: 增加新的产品系列时,只需添加新的工厂和产品类,客户端代码不需要修改。
  3. 一致性: 可以确保一组产品的一致性,因为工厂创建的产品彼此兼容。

缺点:

  1. 增加系统复杂性: 由于需要增加许多抽象类和具体类,系统结构变得复杂。
  2. 难以支持新产品: 如果需要支持新的产品类型,可能需要修改工厂接口,影响已有的代码。

5. 适用场景

  • 多种产品的系列: 当系统需要处理一系列相关的产品,但客户端代码不知道具体的产品类时,抽象工厂模式是合适的选择。
  • 产品兼容性: 当系统中的产品需要保持一致性或兼容性时(例如,一个操作系统的UI库),抽象工厂模式可以帮助管理和维护这些产品的一致性。
  • 产品家族: 需要在产品家族中选择不同的产品时(例如,不同操作系统上的UI组件),抽象工厂模式提供了一种优雅的解决方案。

6. 代码示例

工厂方法模式要求产品必须为同一类型,也就是说,BBA 的工厂只能生产各自的汽车,要生产其他产品(例如:自行车)是不行的,这显然限制了产品的扩展。为了解决这个问题,抽象工厂模式出现了 - 将产品归类分组,然后将好几组产品构成一族。每个工厂负责生产一族产品,而工厂中的每个方法负责生产一种类型的产品。

这样,客户端只需要创建具体工厂的实例,然后调用工厂对象的工厂方法就可以得到所需要的产品对象。

#include <iostream>
#include <string>

// 抽象产品:汽车
class Car {
public:
    virtual void drive() = 0;  // 纯虚函数:驱动汽车
};

// 具体产品:奔驰汽车
class MercedesCar : public Car {
public:
    void drive() override {
        std::cout << "Driving a Mercedes car." << std::endl;
    }
};

// 具体产品:宝马汽车
class BMWCar : public Car {
public:
    void drive() override {
        std::cout << "Driving a BMW car." << std::endl;
    }
};

// 具体产品:奥迪汽车
class AudiCar : public Car {
public:
    void drive() override {
        std::cout << "Driving an Audi car." << std::endl;
    }
};

// 抽象产品:自行车
class Bicycle {
public:
    virtual void ride() = 0;  // 纯虚函数:骑自行车
};

// 具体产品:奔驰自行车
class MercedesBicycle : public Bicycle {
public:
    void ride() override {
        std::cout << "Riding a Mercedes bicycle." << std::endl;
    }
};

// 具体产品:宝马自行车
class BMWBicycle : public Bicycle {
public:
    void ride() override {
        std::cout << "Riding a BMW bicycle." << std::endl;
    }
};

// 具体产品:奥迪自行车
class AudiBicycle : public Bicycle {
public:
    void ride() override {
        std::cout << "Riding an Audi bicycle." << std::endl;
    }
};

// 抽象工厂
class VehicleFactory {
public:
    virtual Car* createCar() = 0;  // 纯虚函数:创建汽车
    virtual Bicycle* createBicycle() = 0;  // 纯虚函数:创建自行车
};

// 具体工厂:奔驰工厂
class MercedesFactory : public VehicleFactory {
public:
    Car* createCar() override {
        return new MercedesCar();  // 创建奔驰汽车
    }
    
    Bicycle* createBicycle() override {
        return new MercedesBicycle();  // 创建奔驰自行车
    }
};

// 具体工厂:宝马工厂
class BMWFactory : public VehicleFactory {
public:
    Car* createCar() override {
        return new BMWCar();  // 创建宝马汽车
    }
    
    Bicycle* createBicycle() override {
        return new BMWBicycle();  // 创建宝马自行车
    }
};

// 具体工厂:奥迪工厂
class AudiFactory : public VehicleFactory {
public:
    Car* createCar() override {
        return new AudiCar();  // 创建奥迪汽车
    }
    
    Bicycle* createBicycle() override {
        return new AudiBicycle();  // 创建奥迪自行车
    }
};

// 客户端代码:使用工厂创建产品
void testVehicleFactory(VehicleFactory* factory) {
    Car* car = factory->createCar();  // 创建汽车
    Bicycle* bicycle = factory->createBicycle();  // 创建自行车

    car->drive();  // 驱动汽车
    bicycle->ride();  // 骑自行车

    delete car;  // 释放汽车内存
    delete bicycle;  // 释放自行车内存
}

int main() {
    VehicleFactory* factory = new MercedesFactory();  // 使用奔驰工厂
    testVehicleFactory(factory);
    delete factory;

    factory = new BMWFactory();  // 使用宝马工厂
    testVehicleFactory(factory);
    delete factory;

    factory = new AudiFactory();  // 使用奥迪工厂
    testVehicleFactory(factory);
    delete factory;

    return 0;
}


http://www.kler.cn/a/281955.html

相关文章:

  • 解决 Spring Boot 中 `Ambiguous mapping. Cannot map ‘xxxController‘ method` 错误
  • 【gitlab】gitlabrunner部署
  • 数据处理与统计分析——05-Pandas中DataFrame的方法、属性、索引等一系列操作
  • Redis-08 Redis集群
  • PyTorch使用教程-深度学习框架
  • React--》如何高效管理前端环境变量:开发与生产环境配置详解
  • minio 大视频观看,下载
  • 【Datawhale AI夏令营】从零上手CV竞赛Task2
  • 025.指纹浏览器-WebGPU指纹+出售成品
  • git-命名规范
  • GPT应用-如何用GPT4.0写一份专业的ppt
  • vue全局参数
  • upload-labs(Pass-18 ~ Pass-21)
  • 0x03 ShowDoc 文件上传漏洞(CNVD-2020-26585)复现
  • 乾元通渠道商中标大理市自然灾害应急能力提升项目
  • MSSQL 手工注入(第一关)
  • 数学建模之数据分析【八】:数据预处理之数据格式化
  • Objective-C 动态调用秘籍:NSInvocation 的魔法
  • 使用matplotlib可视化dataframe:让你的数据更生动有趣
  • 【采集软件】抖音根据关键词批量采集搜索结果工具
  • 使用Hutool操作Excel的时候出现的问题(压缩比问题)
  • 计算机毕业设计选题推荐-保险业务管理系统-Java/Python项目实战
  • 使用canal增量同步ES索引库数据
  • AI模型应该追求全能还是专精
  • 【hot100篇-python刷题记录】【跳跃游戏】
  • 设计模式 7 桥接模式