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


    定义

    工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类来决定实例化哪一个类。工厂方法使得类的实例化延迟到子类,这样可以让客户端在不需要知道具体类的情况下创建对象。工厂方法模式通过使用继承和多态性,允许子类来控制对象的创建方式,能够更好地应对对象创建的复杂性和变化性。
     

    为什么使用工厂方法模式?

    1. 遵循开闭原则

       - 工厂方法模式通过引入新的子类来扩展系统,而不需要修改现有代码,从而符合开闭原则。

    2. 更灵活的对象创建

       - 工厂方法模式将对象创建延迟到子类,这样可以通过重写工厂方法来定制对象的创建过程。

    3. 支持产品族的扩展

       - 当系统中有多个产品等级结构时,可以通过工厂方法模式来管理不同等级的产品创建过程。
     

    实现步骤

    1. 定义抽象产品类

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

    2. 实现具体产品类

       - 实现产品接口的具体产品类,这些类包含了产品的实际业务逻辑。

    3. 定义抽象工厂类

       - 定义一个抽象工厂类,包含一个用于创建产品对象的抽象方法,子类将实现该方法来创建具体产品对象。

    4. 实现具体工厂类

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

    优缺点和适用场景

    优点

    1. 遵循开闭原则

       - 新增产品时无需修改已有系统代码,符合开闭原则。

    2. 更灵活的对象创建

       - 子类可以通过重写工厂方法来定制对象的创建过程,提供更灵活的对象创建机制。

    3. 支持产品族扩展

       - 能够很好地应对产品族的扩展和变化。
     

    缺点

    1. 增加类的数量

       - 每新增一种产品类型,都需要增加一个具体工厂类,可能导致系统中类的数量增加。

    2. 复杂度增加

       - 与简单工厂模式相比,工厂方法模式引入了更多的类和接口,增加了系统的复杂性。
     

    适用场景

    1. 系统需要灵活和可扩展的对象创建机制

       - 当系统需要灵活地创建对象,并且能够应对产品族的变化时,可以使用工厂方法模式。

    2. 遵循开闭原则

       - 当系统需要遵循开闭原则,避免修改现有代码来扩展新功能时,适合使用工厂方法模式。
     

    工厂方法模式与简单工厂模式的对比

    1. 职责分配

       - 简单工厂模式将对象创建集中在一个工厂类中,而工厂方法模式将对象创建延迟到具体子类中,职责更加分散。

    2. 开闭原则

       - 简单工厂模式在引入新产品时需要修改工厂类,违背了开闭原则;工厂方法模式通过新增具体工厂类来扩展新产品,符合开闭原则。

    3. 复杂性

       - 简单工厂模式结构较为简单,适用于创建逻辑不复杂的场景;工厂方法模式结构较为复杂,适用于创建逻辑复杂且需要灵活扩展的场景。
     

    咖啡店的例子

    我们可以使用工厂方法模式来实现咖啡店不同类型咖啡的创建。
    复制代码
    #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 Latte : public Coffee {
    public:
        std::string getDescription() const override {
            return "Latte";
        }
        double cost() const override {
            return 6.0;
        }
    };
    
    // 抽象工厂类
    class CoffeeFactory {
    public:
        virtual ~CoffeeFactory() {}
        virtual std::shared_ptr createCoffee() const = 0;
    };
    
    // 具体工厂类:美式咖啡工厂
    class AmericanoFactory : public CoffeeFactory {
    public:
        std::shared_ptr createCoffee() const override {
            return std::make_shared();
        }
    };
    
    // 具体工厂类:拿铁咖啡工厂
    class LatteFactory : public CoffeeFactory {
    public:
        std::shared_ptr createCoffee() const override {
            return std::make_shared();
        }
    };
    
    int main() {
        // 创建美式咖啡
        std::shared_ptr americanoFactory = std::make_shared();
        std::shared_ptr americano = americanoFactory->createCoffee();
        std::cout << "Description: " << americano->getDescription() << ", Cost: " << americano->cost() << " RMB" << std::endl;
    
        // 创建拿铁咖啡
        std::shared_ptr latteFactory = std::make_shared();
        std::shared_ptr latte = latteFactory->createCoffee();
        std::cout << "Description: " << latte->getDescription() << ", Cost: " << latte->cost() << " RMB" << std::endl;
    
        return 0;
    }
    复制代码

     

  • 相关阅读:
    掌握ChatGPT的正确打开方式
    PostgreSQL 逻辑复制模块(二)
    SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
    三步减少打包机故障
    旅拍摄影技巧&澳大利亚、韩国旅行攻略
    【1】MongoDB的安装以及连接
    配置gateway路由与路径重写规则,验证码503问题的解决
    SpringCloud 常见问题
    基于Echarts实现可视化数据大屏厅店营业效能分析
    哲学视角下的线上虚拟实验
  • 原文地址:https://www.cnblogs.com/best-doraemon/p/18306190