工厂设计模式

文章目录

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


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

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

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


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

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

简单工厂模式优点:

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

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

cpp 复制代码
/* 汽车接口 */
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;
}

二、工厂方法模式

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


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

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

工厂方法模式优点:

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

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

cpp 复制代码
/* 汽车接口 */
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;
}

三、抽象工厂模式

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


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

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

抽象工厂方法模式优点:

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

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

cpp 复制代码
/* 轿车接口 */
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;
}
相关推荐
St_rive8 小时前
Page Object设计模式
java·开发语言·设计模式
烬羽1 天前
NestJS 依赖注入:Controller 里那个没有 new 的 service,到底从哪来的?
设计模式·typescript·nestjs
用户938515635071 天前
工厂模式与 Nest.js 核心思想 —— 从蜜雪冰城到企业级架构
后端·设计模式·nestjs
烬羽2 天前
从 nest new 到 Hello World:一个最小 NestJS 项目,讲透工厂 + 装饰器 + 模块化
设计模式·node.js·nestjs
艺艺生辉3 天前
从if-else到策略模式
后端·设计模式
小林ixn3 天前
单例模式:从弹窗管理到全局状态,一个模式搞定
前端·javascript·设计模式
AI人工智能+电脑小能手3 天前
大白话说Java设计模式-17-装饰器模式(源码剖析篇)
java·spring·设计模式·装饰器模式·源码分析·io流
workflower3 天前
案例 :某交通厅基于AI技术的智能安全运营实践
网络·人工智能·安全·设计模式·机器人
AI人工智能+电脑小能手3 天前
大白话说Java设计模式-16-装饰器模式(业务实战篇)
java·设计模式·装饰器模式·功能扩展·动态增强
workflower4 天前
例二:某汽车制造企业深度融合AI智能体,构建园区网络的智能运维体系
人工智能·机器学习·设计模式·机器人·云计算·汽车·制造