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

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 Button
    window->render(); // 输出:Rendering Windows Window

    // 切换到另一种具体工厂
    factory = std::make_unique<MacFactory>();

    button = factory->createButton();
    window = factory->createWindow();

    button->render(); // 输出:Rendering Mac Button
    window->render(); // 输出:Rendering Mac Window

    return 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. 引入依赖注入框架
    通过依赖注入简化工厂选择的逻辑,使得代码更易于维护和测试。


总结

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


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

相关文章:

  • 最左前缀匹配原则
  • FLASK 上传文件
  • 华为2024嵌入式研发面试题
  • C#类型转换
  • EasyCVR视频汇聚平台如何配置webrtc播放地址?
  • RV1126+FFMPEG推流项目(3)VI模块视频编码流程
  • CVPR 2024 自动驾驶方向总汇
  • RHCE的基本学习路线
  • Leetcode 2140. 解决智力问题 动态规划
  • 图解Git——分支管理《Pro Git》
  • Transformer架构和Transformers 库和Hugging Face
  • 【Python】第一弹---解锁编程新世界:深入理解计算机基础与Python入门指南
  • MongoDB 学习指南与资料分享
  • 面向对象三大特征之一——多态【红色标记】
  • c语言-嵌入式专辑~
  • ASP.NET Core - 依赖注入(三)
  • CF 230A.Dragons(Java实现)
  • Golang——GPM调度器
  • uniapp实现“到这儿去”、拨打电话功能
  • 【鸿蒙Next】protobuf如何使用
  • [MySQL | 二、基本数据类型]
  • Scikit-Learn快速入门
  • nginx 配置ssl_dhparam好处及缺点
  • 怎样应对发现的小红书笔记详情API安全风险?
  • 心有花木,向阳而生:拥抱生活的无限可能
  • ADC(Analog-to-digital converter)模拟-数字转换器