工厂设计模式

文章目录

插图来自: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;
}
相关推荐
wrx繁星点点2 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干3 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨4 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉13 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点13 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰13 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus13 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵13 小时前
设计模式-迭代器
设计模式
lexusv8ls600h15 小时前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式
sniper_fandc17 小时前
抽象工厂模式
java·设计模式·抽象工厂模式