工厂模式 - 工厂方法模式、抽象工厂模式

引言

工厂模式(Factory Pattern)是设计模式中创建型模式的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂模式主要分为两种:工厂方法模式抽象工厂模式

本文将详细介绍工厂方法模式和抽象工厂模式的概念、实现方式以及在C++中的应用。

工厂方法模式

概念

工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类。

优点

  1. 解耦:将对象的创建与使用分离,降低代码的耦合度。
  2. 扩展性好:新增产品类时,只需增加相应的工厂类,无需修改现有代码。
  3. 符合开闭原则:对扩展开放,对修改关闭。

缺点

  1. 类的数量增加:每增加一个产品类,就需要增加一个对应的工厂类,导致类的数量增加。
  2. 复杂性增加:对于简单的对象创建,使用工厂方法模式可能会增加代码的复杂性。

实现

下面是一个简单的工厂方法模式的实现示例:

cpp 复制代码
#include <iostream>
#include <string>

// 产品接口
class Product {
public:
    virtual ~Product() {}
    virtual void use() = 0;
};

// 具体产品A
class ProductA : public Product {
public:
    void use() override {
        std::cout << "Using Product A" << std::endl;
    }
};

// 具体产品B
class ProductB : public Product {
public:
    void use() override {
        std::cout << "Using Product B" << std::endl;
    }
};

// 工厂接口
class Factory {
public:
    virtual ~Factory() {}
    virtual Product* createProduct() = 0;
};

// 具体工厂A
class FactoryA : public Factory {
public:
    Product* createProduct() override {
        return new ProductA();
    }
};

// 具体工厂B
class FactoryB : public Factory {
public:
    Product* createProduct() override {
        return new ProductB();
    }
};

int main() {
    Factory* factoryA = new FactoryA();
    Product* productA = factoryA->createProduct();
    productA->use();

    Factory* factoryB = new FactoryB();
    Product* productB = factoryB->createProduct();
    productB->use();

    delete productA;
    delete productB;
    delete factoryA;
    delete factoryB;

    return 0;
}

应用场景

工厂方法模式适用于以下场景:

  1. 不确定对象的类型:当创建对象时,不确定具体要创建哪种类型的对象。
  2. 需要扩展:当需要扩展系统,增加新的产品类时,使用工厂方法模式可以避免修改现有代码。

抽象工厂模式

概念

抽象工厂模式(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式是工厂方法模式的扩展,它用于创建一组相关的对象。

优点

  1. 高内聚:将相关的产品族集中在一起创建,保证产品族的一致性。
  2. 解耦:将产品的创建与使用分离,降低代码的耦合度。
  3. 符合开闭原则:对扩展开放,对修改关闭。

缺点

  1. 类的数量增加:每增加一个产品族,就需要增加一个对应的工厂类,导致类的数量增加。
  2. 复杂性增加:对于简单的对象创建,使用抽象工厂模式可能会增加代码的复杂性。

实现

下面是一个简单的抽象工厂模式的实现示例:

cpp 复制代码
#include <iostream>
#include <string>

// 抽象产品A
class AbstractProductA {
public:
    virtual ~AbstractProductA() {}
    virtual void use() = 0;
};

// 具体产品A1
class ProductA1 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using Product A1" << std::endl;
    }
};

// 具体产品A2
class ProductA2 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using Product A2" << std::endl;
    }
};

// 抽象产品B
class AbstractProductB {
public:
    virtual ~AbstractProductB() {}
    virtual void use() = 0;
};

// 具体产品B1
class ProductB1 : public AbstractProductB {
public:
    void use() override {
        std::cout << "Using Product B1" << std::endl;
    }
};

// 具体产品B2
class ProductB2 : public AbstractProductB {
public:
    void use() override {
        std::cout << "Using Product B2" << std::endl;
    }
};

// 抽象工厂
class AbstractFactory {
public:
    virtual ~AbstractFactory() {}
    virtual AbstractProductA* createProductA() = 0;
    virtual AbstractProductB* createProductB() = 0;
};

// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ProductA1();
    }

    AbstractProductB* createProductB() override {
        return new ProductB1();
    }
};

// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ProductA2();
    }

    AbstractProductB* createProductB() override {
        return new ProductB2();
    }
};

int main() {
    AbstractFactory* factory1 = new ConcreteFactory1();
    AbstractProductA* productA1 = factory1->createProductA();
    AbstractProductB* productB1 = factory1->createProductB();
    productA1->use();
    productB1->use();

    AbstractFactory* factory2 = new ConcreteFactory2();
    AbstractProductA* productA2 = factory2->createProductA();
    AbstractProductB* productB2 = factory2->createProductB();
    productA2->use();
    productB2->use();

    delete productA1;
    delete productB1;
    delete factory1;
    delete productA2;
    delete productB2;
    delete factory2;

    return 0;
}

应用场景

抽象工厂模式适用于以下场景:

  1. 产品族:当需要创建一组相关的产品时,使用抽象工厂模式可以保证产品族的一致性。
  2. 跨平台:当需要为不同的平台创建一组相关的产品时,使用抽象工厂模式可以方便地切换平台。

总结

工厂模式是一种非常实用的设计模式,它将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂方法模式适用于创建单一产品,而抽象工厂模式适用于创建一组相关的产品。在实际开发中,根据具体需求选择合适的工厂模式,可以提高代码的可维护性和可扩展性。

希望本文能帮助你更好地理解工厂方法模式和抽象工厂模式的概念、实现方式以及应用场景。如果你有任何问题或建议,欢迎在评论区留言讨论。

相关推荐
不甘先生15 分钟前
Go 中 type、方法与指针接收者:从 str_name.Name() 看懂 Go 的类型系统
开发语言·后端·golang
tudousisi22228 分钟前
CSP 第3题训练 Day 5|CSP202509C HTTP 头信息|Blog A
c++
quantdash_cc1 小时前
Python 股票 K 线数据质量校验:字段、缺失值、重复行和价格异常
开发语言·python·数据分析·量化交易·股票数据·quantdash
Zenova EdgeOS1 小时前
工业网关重试机制:从固定间隔到指数退避的工程实战
开发语言·网络·php
闻缺陷则喜何志丹1 小时前
【动态规划】P10726 [GESP202406 八级] 空间跳跃|普及+
c++·算法·动态规划·洛谷
嘻哈baby1 小时前
Go 函数中的参数为什么不支持默认值?
java·开发语言·jvm
一晌小贪欢2 小时前
python-第29天:Python面向对象之多态与抽象类
开发语言·python·数据可视化·面向对象·python办公·python多态
Chester_19992 小时前
CSP202312C.树上搜索
开发语言·数据结构·c++·蓝桥杯·stl
Figo_Cheung2 小时前
Figo共振网络宇宙演化论(RNC) :从原初对称破缺到全息大和谐的演化路径研究
开发语言·php·量子计算
重生之我来学Python2 小时前
Git-SVN 混合开发,从入门到精通!
开发语言·git·svn·github