• 工厂设计模式


    插图来自: https://refactoringguru.cn/design-patterns/catalog


    一、简单工厂模式 & 静态工厂模式

    简单工厂模式严格来说并不是一种设计模式,而更像是一种编程习惯。简单工厂模式在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来提供新创建的对象

    当这个提供对象接口被定义为静态方法时,简单工厂模式也被称为静态工厂模式


    简单工厂模式包含如下角色:

    • 抽象产品:定义产品规范,描述产品主要特性和功能,是所有具体产品的基类。
    • 具体产品:实现或者继承抽象产品。
    • 具体工厂:提供了创建产品的方法,调用者通过该方法来获取产品。

    简单工厂模式优点:

    • 封装了创建对象的过程:当一个调用者想创建一个对象时只需要知道其名称就可以了。
    • 对象创建和业务逻辑被分开:如果要添加新产品只需要修改工厂类,而不需要在原代码中修改,降低了客户代码修改的可能性,在一定程度上增加了代码的可扩展性。

    简单工厂模式缺点:增加新产品时需要修改工厂类的代码,违背了开闭原则(对扩展开放,对修改封闭)。

    /* 汽车接口 */
    class Car {
    public:
        virtual void drive() = 0;
    
        virtual ~Car() = default;
    };
    
    /* 轿车 */
    class Sedan : public Car {
    public:
        void drive() override {
            cout << "Sedan is driving." << endl;
        }
    };
    
    /* 卡车 */
    class Truck : public Car {
    public:
        void drive() override {
            cout << "Truck is driving." << endl;
        }
    };
    
    /* 静态工厂类 */
    class CarFactory {
    public:
        static Car *createCar(const string &carType) {
            if (carType == "Sedan") {
                return new Sedan();
            } else if (carType == "Truck") {
                return new Truck();
            } else {
                return nullptr;
            }
        }
    };
    
    int main() {
        unique_ptr<Car> sedan(CarFactory::createCar("Sedan"));
        unique_ptr<Car> truck(CarFactory::createCar("Truck"));
    
        sedan->drive();
        truck->drive();
    
        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

    二、工厂方法模式

    工厂方法模式是一种创建型设计模式,其在父类中提供一个创建对象的方法接口允许子类决定所要实例化对象的类型。工厂方法模式使一个产品类的实例化延迟到工厂的子类中进行。

    在这里插入图片描述


    工厂方法模式包含如下角色:

    • 抽象产品:定义产品规范,描述产品主要特性和功能,是所有具体产品的基类。
    • 具体产品:实现或者继承抽象产品,由具体工厂来创建,与具体工厂之间一一对应。
    • 抽象工厂:提供了创建产品的接口,调用者通用它访问具体工厂的工厂方法来创建产品。
    • 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。

    工厂方法模式优点:

    • 用户只需要知道具体工厂的名称就可以得到想要的产品,而无需知道产品的具体创建过程,从而避免了用户和具体产品之间的紧密耦合。
    • 可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护,满足单一职责原则
    • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则

    工厂方法模式缺点:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,增加了系统的复杂度

    /* 汽车接口 */
    class Car {
    public:
        virtual void drive() = 0;
    
        virtual ~Car() = default;
    };
    
    /* 工厂接口 */
    class CarFactory {
    public:
        virtual Car *createCar() = 0;
    
        virtual ~CarFactory() = default;
    };
    
    /* 轿车 */
    class Sedan : public Car {
    public:
        void drive() override {
            cout << "Sedan is driving." << endl;
        }
    };
    
    /* 卡车 */
    class Truck : public Car {
    public:
        void drive() override {
            cout <<  "Truck is driving." << endl;
        }
    };
    
    /* 轿车工厂 */
    class SedanFactory : public CarFactory {
    public:
        Car *createCar() override {
            return new Sedan();
        }
    };
    
    /* 卡车工厂 */
    class TruckFactory : public CarFactory {
    public:
        Car *createCar() override {
            return new Truck();
        }
    };
    
    int main() {
        unique_ptr<CarFactory> sedan_factory(new SedanFactory());
        unique_ptr<CarFactory> truck_factory(new TruckFactory());
    
        unique_ptr<Car> sedan(sedan_factory->createCar());
        unique_ptr<Car> truck(truck_factory->createCar());
    
        sedan->drive();
        truck->drive();
        
        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

    三、抽象工厂模式

    抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产某个单一的产品,而抽象工厂模式可生产一系列相关的产品

    在这里插入图片描述


    抽象工厂模式包含如下角色:

    • 抽象产品:定义产品规范,描述产品主要特性和功能,是所有具体产品的基类。
    • 具体产品:实现或者继承抽象产品,由具体工厂来创建,与具体工厂之间是多对一的关系。
    • 抽象工厂:提供了创建产品的接口,调用者通用它访问具体工厂的工厂方法来创建一系列相关的产品。
    • 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。

    抽象工厂方法模式优点:

    • 可以确保同一工厂生成的产品相互匹配,比如下例中的福特工厂不会生产出沃尔沃汽车。
    • 可以避免客户端和具体产品代码的耦合。
    • 基于工厂方法模式改进,同样满足单一职责原则和开闭原则

    抽象工厂方法模式缺点:代码较为复杂。同时,与工厂方法类似,每当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。比如我们在下面代码中添加一个有关商务车的方法,包括抽象工厂在内的所有工厂类都需要进行修改。

    /* 轿车接口 */
    class Sedan {
    public:
        virtual void drive() = 0;
    
        virtual ~Sedan() = default;
    };
    
    /* 卡车接口 */
    class Truck {
    public:
        virtual void drive() = 0;
    
        virtual ~Truck() = default;
    };
    
    /* 工厂接口 */
    class CarFactory {
    public:
        virtual Sedan *createSedan() = 0;
    
        virtual Truck *createTruck() = 0;
    
        virtual ~CarFactory() = default;
    };
    
    /* 福特轿车 */
    class FordSedan : public Sedan {
    public:
        void drive() override {
            cout << "Ford sedan is driving." << endl;
        }
    };
    
    /* 福特卡车 */
    class FordTruck : public Truck {
    public:
        void drive() override {
            cout << "Ford Truck is driving." << endl;
        }
    };
    
    /* 沃尔沃轿车 */
    class VolvoSedan : public Sedan {
    public:
        void drive() override {
            cout << "Volvo sedan is driving." << endl;
        }
    };
    
    /* 沃尔沃卡车 */
    class VolvoTruck : public Truck {
    public:
        void drive() override {
            cout << "Volvo Truck is driving." << endl;
        }
    };
    
    /* 福特工厂 */
    class FordFactory : public CarFactory {
    public:
        Sedan *createSedan() override {
            return new FordSedan();
        }
    
        Truck *createTruck() override {
            return new FordTruck();
        }
    };
    
    /* 沃尔沃工厂 */
    class VolvoFactory : public CarFactory {
    public:
        Sedan *createSedan() override {
            return new VolvoSedan();
        }
    
        Truck *createTruck() override {
            return new VolvoTruck();
        }
    };
    
    int main() {
        unique_ptr<CarFactory> ford_factory = make_unique<FordFactory>();
        unique_ptr<CarFactory> volvo_factory = make_unique<VolvoFactory>();
    
        unique_ptr<Sedan> ford_sedan(ford_factory->createSedan());
        unique_ptr<Truck> ford_truck(ford_factory->createTruck());
        unique_ptr<Sedan> volvo_sedan(ford_factory->createSedan());
        unique_ptr<Truck> volvo_truck(ford_factory->createTruck());
    
        ford_sedan->drive();
        ford_truck->drive();
        volvo_sedan->drive();
        volvo_truck->drive();
    
        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
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    在这里插入图片描述

  • 相关阅读:
    如何看待2022年秋招Java后端开发岗一片红海?
    EasyNLP 开源中文 NLP 算法框架
    Azkaban安装及配置
    二元关系及关系代数中的象集、除运算
    数据结构题目收录(七)
    作业帮 x TiDB丨多元化海量数据业务的支撑
    力扣 1319. 连通网络的操作次数
    LLaMA模型指令微调 字节跳动多模态视频大模型 Valley 论文详解
    [云原生k8s] k8s之持久化存储PV、PVC
    体现技术深度(无法速成)
  • 原文地址:https://blog.csdn.net/qq_43686863/article/details/134254886