• C++设计模式(工厂方法模式)



    前言

    本篇文章来带大家学习C++中的工厂方法模式

    一、工厂方法模式介绍

    工厂方法模式是一种创建型设计模式,用于通过工厂方法创建对象而不需要明确指定其具体类。该模式通过定义一个创建对象的接口,但将具体的对象创建延迟到其子类中。这样可以将对象的创建与使用分离,提高代码的灵活性和可扩展性。

    UML结构图:

    在这里插入图片描述

    二、工厂方法模式和简单工厂模式对比

    1.实现方式:

    简单工厂模式:由一个工厂类负责创建对象,根据传入的参数或条件来决定创建哪种具体对象。相当于一个工厂类集中了所有产品的创建逻辑。
    工厂方法模式:将对象的创建延迟到子类中,每个具体产品都有对应的工厂类,负责创建该产品。每个工厂类只负责创建一种具体的产品。

    2.灵活性和扩展性:

    简单工厂模式:通过一个工厂类集中管理对象的创建,增加新的产品时需要修改工厂类的代码,不符合开闭原则(对扩展开放,对修改关闭)。
    工厂方法模式:每个具体产品都有对应的工厂类,新增产品时只需要添加新的具体产品和对应的工厂类,不需要修改现有代码。符合开闭原则。

    3.耦合度:

    简单工厂模式:客户端代码需要依赖工厂类,通过工厂类创建具体产品的实例。
    工厂方法模式:客户端代码依赖抽象工厂和抽象产品类,通过抽象工厂创建具体产品的实例。客户端代码与具体工厂类和具体产品类解耦。

    4.类的数量:

    简单工厂模式:只需要一个工厂类负责创建所有产品,工厂类可能会变得很大。
    工厂方法模式:每个具体产品都有对应的工厂类,类的数量比简单工厂模式多,但可以更细粒度地管理对象的创建。

    三、工厂方法模式适用场景

    1.对象的创建需要遵循特定的接口或抽象类:工厂方法模式适用于创建一组相关对象,这些对象共享一个公共的接口或抽象类。通过定义抽象工厂和具体工厂类,可以确保创建的对象都符合同一接口或抽象类的定义。

    2.需要通过子类来决定创建的具体对象:工厂方法模式将对象的创建延迟到子类中,子类可以根据具体需求来选择实现哪种具体对象。这样可以在不修改客户端代码的情况下,动态地增加或切换具体对象的类型。

    3.需要通过扩展来添加新的产品:如果系统中需要添加新的产品,工厂方法模式可以提供一种扩展机制,使得添加新产品变得更加容易。只需创建新的具体产品类和对应的具体工厂类,而不需要修改已有的代码。

    4.需要对客户端代码与具体产品的耦合进行解耦:通过引入抽象工厂和具体工厂类,工厂方法模式可以将客户端代码与具体产品的创建过程解耦。客户端只需要依赖于抽象工厂和抽象产品类,而不需要自己直接创建具体对象,从而降低了耦合度。

    四、工厂方法模式示例代码

    #include 
    #include 
    
    // 抽象产品类
    class Product {
    public:
        virtual void use() const = 0;
    };
    
    // 具体产品类 A
    class ConcreteProductA : public Product {
    public:
        void use() const override {
            std::cout << "Using ConcreteProductA" << std::endl;
        }
    };
    
    // 具体产品类 B
    class ConcreteProductB : public Product {
    public:
        void use() const override {
            std::cout << "Using ConcreteProductB" << std::endl;
        }
    };
    
    // 抽象工厂类
    class Factory {
    public:
        virtual Product* createProduct() const = 0;
    };
    
    // 具体工厂类 A
    class ConcreteFactoryA : public Factory {
    public:
        Product* createProduct() const override {
            return new ConcreteProductA();
        }
    };
    
    // 具体工厂类 B
    class ConcreteFactoryB : public Factory {
    public:
        Product* createProduct() const override {
            return new ConcreteProductB();
        }
    };
    
    int main() {
        // 使用具体工厂类 A 创建产品对象
        Factory* factoryA = new ConcreteFactoryA();
        Product* productA = factoryA->createProduct();
        productA->use();
    
        delete productA;
        delete factoryA;
    
        // 使用具体工厂类 B 创建产品对象
        Factory* factoryB = new ConcreteFactoryB();
        Product* productB = factoryB->createProduct();
        productB->use();
    
        delete productB;
        delete factoryB;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    总结

    本篇文章就讲解到这里。

  • 相关阅读:
    中断:PL硬中断,基地址,优先级。
    C#调用bartender进行动态打印以及批量打印的完整教程
    AUTOSAR协议栈 - 功能简介
    JAVA面试全集
    ElementUI validate 验证结果错误的问题解决过程
    Android 9 User包开放root权限和串口交互
    Live800:智能客服时代,智能营销机器人有哪些套路?
    Medium: 9 Important Things to Remember for AB Test
    39、Docker(镜像命令)
    Linux学习
  • 原文地址:https://blog.csdn.net/m0_49476241/article/details/132482670