创建型模式(Creational Patterns)之工厂模式(Factory Pattern)之工厂方法模式(Factory Method Pattern)

1. 工厂方法模式(Factory Method Pattern)

        将对象的创建延迟到子类中实现,每个具体产品类都有一个对应的工厂类负责创建,从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必关心具体的实现细节。这种模式符合开放-封闭原则,对扩展开放、对修改关闭。

        不同于 简单工厂模式 定义一个工厂方法来创建产品,工厂方法模式 的 每个产品都有一个对应的工厂类来创建。这样每个产品类和工厂类相互独立,可以独立进行扩展,符合开放-封闭原则。例如,在一个图形绘制软件中,可以使用 工厂方法模式 来创建不同类型的图形对象,如圆形、矩形、三角形等,每个图形都有一个对应的工厂类来创建。

假设我们要设计一个电子产品工厂来生产不同类型的产品,如手机、电视、电脑等。如果使用 简单工厂模式,我们需要一个工厂类来创建所有不同类型的电子产品,客户端代码需要指定电子产品类型,工厂类根据类型来创建相应的产品对象。但是,随着产品类型的增加,工厂类的代码会越来越复杂,难以维护和扩展。

相反,如果使用 工厂方法模式,每个产品类型都有一个对应的工厂类来创建,工厂方法 可以独立进行扩展,每个工厂类只需要关心自己负责的产品类型,代码更加清晰和易于维护。例如,手机工厂类负责创建手机产品对象,电视工厂类负责创建电视产品对象,电脑工厂类负责创建电脑产品对象等。客户端代码只需要知道所需的产品类型,选择对应的工厂类即可,不需要知道具体的创建细节。

2. 结构

2.1 角色

工厂方法模式是在简单工厂模式上的改进,主要包含如下几个角色及组件

  • 抽象工厂(Creator):整个工厂模式的核心角色,它与应用无关,主要在创建模式中规范和产品对应的工厂对象的标准化定义。
  • 具体工厂(Concrete Creator):实现了抽象工厂的具体工厂类,该类型是和应用直接交互的具体实现类,在应用程序中调用,用于创建产品对象。
  • 抽象产品(Product):工厂方法模式创建的所有类型的超级父类,该类型和具体业务有关,用于规范工厂方法模式中创建的方法对象具备的公共特征行为。
  • 具体产品(Concrete Product):该类型实现了抽象产品 父类,是工厂方法模式中具体创建的实例对象。

2.2 类图

3.优缺点

优点:‌

  • 遵循开闭原则:‌工厂方法模式允许在不修改原有代码的情况下增加新的产品,‌这符合软件工程中的开闭原则,‌即对扩展开放,‌对修改关闭。‌当需要添加新产品时,‌只需要添加具体的产品类和对应的工厂类,‌而不需要修改已有的抽象工厂和客户端代码。
  • 高扩展性:‌由于所有的具体工厂类都继承自同一个抽象父类,‌这使得系统在加入新产品时具有良好的扩展性。‌这种模式鼓励使用多态性,‌允许工厂自主确定创建何种产品对象,‌而如何创建这个对象的细节则完全封装在具体工厂内部。
  • 隐藏了创建对象的复杂性:‌用户或客户端不需要关心创建对象的细节,‌甚至不需要知道具体产品类的类名,‌只需要关心所需产品对应的工厂即可。‌这有助于减少客户端与具体产品类之间的耦合度

缺点:‌

  1. 增加了类的数量:‌当有成千上万个类型的产品时,‌就需要有成千上万个工厂类来生产这些产品。‌这会增加系统的复杂度,‌需要编译和运行的类数量增加,‌可能会给系统带来额外的开销。‌
  2. 增加了系统的复杂度:‌在添加新产品时,‌需要编写新的具体产品类,‌并且还要提供与之对应的具体工厂类。‌这会导致系统中类的个数成对增加,‌从而增加了系统的复杂度。‌

4.示例

#include <iostream>
#include <string>

// 产品接口
class Animal {
public:
    virtual void makeSound() = 0; // 纯虚函数
    virtual ~Animal() {} // 虚析构函数
};

// 具体产品
class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Woof!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Meow!" << std::endl;
    }
};

// 工厂接口
class AnimalFactory {
public:
    virtual Animal* createAnimal() = 0; // 纯虚函数,工厂方法
    virtual ~AnimalFactory() {} // 虚析构函数
};

// 具体工厂
class DogFactory : public AnimalFactory {
public:
    Animal* createAnimal() override {
        return new Dog();
    }
};

class CatFactory : public AnimalFactory {
public:
    Animal* createAnimal() override {
        return new Cat();
    }
};

// 客户端代码,使用工厂方法模式
int main() {
    AnimalFactory* factory;

    // 根据用户输入或条件选择具体的工厂
    std::string type;
    std::cout << "Enter the type of animal factory ('dog' or 'cat'): ";
    std::cin >> type;

    if (type == "dog") {
        factory = new DogFactory();
    } else if (type == "cat") {
        factory = new CatFactory();
    } else {
        std::cout << "Invalid factory type." << std::endl;
        return 1;
    }

    // 使用工厂创建对象
    Animal* animal = factory->createAnimal();
    animal->makeSound();
    delete animal; // 使用完对象后,记得释放内存
    delete factory; // 释放工厂对象

    return 0;
}
  • Animal 是一个产品接口,声明了所有动物必须实现的 makeSound 方法。
  • DogCat 是具体产品,它们继承自 Animal 并实现了 makeSound 方法。
  • AnimalFactory 是工厂接口,声明了 createAnimal 方法用于创建动物对象。
  • DogFactoryCatFactory 是具体工厂,它们继承自 AnimalFactory 并实现了 createAnimal 方法,分别返回 DogCat 的实例。
  • main 函数中,我们根据用户输入来创建相应的工厂对象,然后使用该工厂对象创建动物对象。

        工厂方法模式允许系统在不修改客户端代码的情况下引入新的产品,提高了系统的扩展性和可维护性。

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的小七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值