• 设计模式之抽象工厂模式(学习笔记)


    定义

    抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。抽象工厂模式将对象的创建过程抽象化,允许子类通过实现具体工厂类来定制对象的创建。

    为什么使用抽象工厂模式

    1. 产品族的一致性

      • 抽象工厂模式确保同一产品族中的对象之间的一致性。
    2. 部分遵循开闭原则

      • 可以通过添加新的具体工厂类来扩展新的产品族,而不需要修改现有代码,符合开闭原则。
      • 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。
    3. 隐藏对象创建细节

      • 抽象工厂模式将具体产品的创建过程隐藏起来,客户端只需要使用工厂提供的接口来获取对象。

    实现步骤

    1. 定义抽象产品类

      • 定义所有具体产品类的共同接口,客户端将通过这个接口来使用具体产品。
    2. 实现具体产品类

      • 实现产品接口的具体产品类,这些类包含了产品的实际业务逻辑。
    3. 定义抽象工厂类

      • 定义一个抽象工厂类,包含用于创建一系列相关或依赖对象的抽象方法,子类将实现这些方法来创建具体产品对象。
    4. 实现具体工厂类

      • 继承抽象工厂类并实现其抽象方法,具体工厂类负责创建具体产品对象。

    优缺点和适用场景

    优点

    1. 产品族的一致性

      • 确保同一产品族中的对象之间的一致性。
    2. 部分符合开闭原则

      • 可以通过添加新的具体工厂类来扩展新的产品族,符合开闭原则。
    3. 隐藏对象创建细节

      • 客户端无需知道具体产品的创建过程,只需要通过工厂接口获取对象。

    缺点

    1. 增加系统复杂性

      • 引入了更多的类,增加了系统的复杂性。
    2. 不完全符合开闭原则

      • 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。

    适用场景

    1. 系统需要创建一系列相关或依赖的对象

      • 当系统需要创建一系列相关或依赖的对象,并且确保这些对象之间的一致性时,适合使用抽象工厂模式。
    2. 产品族扩展

      • 当系统需要通过增加新的产品族来扩展功能,而不需要修改现有代码时,适合使用抽象工厂模式。

    简单工厂模式、工厂方法模式与抽象工厂模式的比较

    特性
    简单工厂模式
    工厂方法模式
    抽象工厂模式
    创建对象的职责
    单一工厂类负责所有产品创建
    子类决定创建具体对象
    子类决定创建一系列相关对象
    遵循开闭原则
    不符合,增加新产品需修改工厂类
    符合,增加新产品无需修改工厂类
    部分符合,增加产品族符合
    系统复杂性
    较低
    中等
    较高
    产品族一致性支持
    不支持
    不支持
    支持

    咖啡店的例子

    我们可以使用抽象工厂模式来实现一个咖啡店系统,该系统可以创建不同种类的咖啡及其配套的杯子和勺子。
    复制代码
    #include 
    #include 
    #include <string>
    
    
    // 抽象产品类:咖啡
    class Coffee {
    public:
        virtual ~Coffee() {}
        virtual std::string getDescription() const = 0;
        virtual double cost() const = 0;
    };
    
    
    // 具体产品类:美式咖啡
    class Americano : public Coffee {
    public:
        std::string getDescription() const override {
            return "Americano";
        }
        double cost() const override {
            return 5.0;
        }
    };
    
    
    // 抽象产品类:咖啡杯
    class CoffeeCup {
    public:
        virtual ~CoffeeCup() {}
        virtual std::string getDescription() const = 0;
    };
    
    
    // 具体产品类:美式咖啡杯
    class AmericanoCup : public CoffeeCup {
    public:
        std::string getDescription() const override {
            return "Americano Cup";
        }
    };
    
    
    // 抽象产品类:咖啡勺
    class CoffeeSpoon {
    public:
        virtual ~CoffeeSpoon() {}
        virtual std::string getDescription() const = 0;
    };
    
    
    // 具体产品类:美式咖啡勺
    class AmericanoSpoon : public CoffeeSpoon {
    public:
        std::string getDescription() const override {
            return "Americano Spoon";
        }
    };
    
    
    // 抽象工厂类
    class CoffeeFactory {
    public:
        virtual ~CoffeeFactory() {}
        virtual std::shared_ptr createCoffee() const = 0;
        virtual std::shared_ptr createCoffeeCup() const = 0;
        virtual std::shared_ptr createCoffeeSpoon() const = 0;
    };
    
    
    // 具体工厂类:美式咖啡工厂
    class AmericanoFactory : public CoffeeFactory {
    public:
        std::shared_ptr createCoffee() const override {
            return std::make_shared();
        }
        std::shared_ptr createCoffeeCup() const override {
            return std::make_shared();
        }
        std::shared_ptr createCoffeeSpoon() const override {
            return std::make_shared();
        }
    };
    
    
    int main() {
        // 创建美式咖啡及其配套杯子和勺子
        std::shared_ptr americanoFactory = std::make_shared();
        std::shared_ptr americano = americanoFactory->createCoffee();
        std::shared_ptr americanoCup = americanoFactory->createCoffeeCup();
        std::shared_ptr americanoSpoon = americanoFactory->createCoffeeSpoon();
    
    
        std::cout << "Coffee: " << americano->getDescription() << ", Cost: " << americano->cost() << std::endl;
        std::cout << "Cup: " << americanoCup->getDescription() << std::endl;
        std::cout << "Spoon: " << americanoSpoon->getDescription() << std::endl;
    
    
        return 0;
    }
    复制代码

     

  • 相关阅读:
    Default Probability
    内部类_Java
    ArcGIS:如何使用成本距离分析确定学校距离目标点的最短成本距离?
    机器学习实战(01)-人工智能概要
    [C/C++] 数据结构 LeetCode:用队列实现栈
    代码行统计工具---cloc(Count Lines of Code)
    硬件描述语言 Chisel 入门教程
    跨平台开发方案调研
    FRED应用:激光二极管光源耦合到光纤的仿真
    数据结构(计算机存储、组织数据方式)
  • 原文地址:https://www.cnblogs.com/best-doraemon/p/18307485