【C++】简单工厂模式/工厂方法模式/抽象工厂模式对比

目录

抽象工厂模式、简单工厂模式和工厂方法模式都是创建型设计模式,它们的核心目的都是将对象的创建和使用分离,但在实现复杂度、灵活性和应用场景上存在显著差异。以下从定义、结构、适用场景和代码示例四个方面进行对比分析:

一、简单工厂模式(Simple Factory Pattern)

定义与结构

  • 定义:简单工厂模式是一种创建对象的方式,它将对象的创建逻辑封装在一个工厂类中,通过传入参数决定创建哪种产品。
  • 核心角色:
    • 工厂类(Factory):负责创建产品的静态方法。
    • 抽象产品(Product):定义产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 产品种类较少且创建逻辑简单。
  • 客户端只需通过参数指定需要创建的产品,不关心创建细节。

代码示例

cpp 复制代码
// 抽象产品
class Shape {
public:
    virtual void draw() = 0;
    virtual ~Shape() = default;
};

// 具体产品
class Circle : public Shape {
public:
    void draw() override { std::cout << "Circle::draw()" << std::endl; }
};

class Rectangle : public Shape {
public:
    void draw() override { std::cout << "Rectangle::draw()" << std::endl; }
};

// 简单工厂
class ShapeFactory {
public:
    static std::unique_ptr<Shape> createShape(const std::string& type) {
        if (type == "circle") return std::make_unique<Circle>();
        if (type == "rectangle") return std::make_unique<Rectangle>();
        return nullptr; // 错误处理
    }
};

// 客户端使用
void client() {
    auto circle = ShapeFactory::createShape("circle");
    circle->draw(); // 输出: Circle::draw()
}

特点

  • 优点:实现简单,将对象创建集中管理。
  • 缺点:工厂类职责过重,新增产品需修改工厂类,违反开闭原则。

二、工厂方法模式(Factory Method Pattern)

定义与结构

  • 定义:工厂方法模式定义创建对象的接口,让子类决定实例化哪个类。工厂方法将产品的创建延迟到子类。
  • 核心角色:
    • 抽象工厂(AbstractFactory):声明工厂方法,返回抽象产品。
    • 具体工厂(ConcreteFactory):实现工厂方法,创建具体产品。
    • 抽象产品(Product):定义产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 当一个类不知道它所需要的对象的类时(如框架设计)。
  • 当一个类希望由其子类来指定创建对象时。
  • 当类将创建对象的职责委托给多个子类中的某一个,并且希望在运行时动态指定时。

代码示例

cpp 复制代码
// 抽象产品
class Product {
public:
    virtual void operation() = 0;
    virtual ~Product() = default;
};

// 具体产品
class ConcreteProductA : public Product {
public:
    void operation() override { std::cout << "ConcreteProductA::operation()" << std::endl; }
};

class ConcreteProductB : public Product {
public:
    void operation() override { std::cout << "ConcreteProductB::operation()" << std::endl; }
};

// 抽象工厂
class Factory {
public:
    virtual std::unique_ptr<Product> createProduct() = 0;
    virtual ~Factory() = default;
};

// 具体工厂
class ConcreteFactoryA : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductA>();
    }
};

class ConcreteFactoryB : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductB>();
    }
};

// 客户端使用
void client(Factory& factory) {
    auto product = factory.createProduct();
    product->operation();
}

// 使用示例
int main() {
    ConcreteFactoryA factoryA;
    client(factoryA); // 输出: ConcreteProductA::operation()
    
    ConcreteFactoryB factoryB;
    client(factoryB); // 输出: ConcreteProductB::operation()
}

特点

  • 优点:符合开闭原则,新增产品只需添加新的具体工厂,无需修改抽象工厂和客户端。
  • 缺点:工厂子类过多时会导致代码复杂度增加。

三、抽象工厂模式(Abstract Factory Pattern)

定义与结构

  • 定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
  • 核心角色:
    • 抽象工厂(AbstractFactory):声明创建多个抽象产品的方法。
    • 具体工厂(ConcreteFactory):实现抽象工厂的方法,创建一组具体产品。
    • 抽象产品族(AbstractProduct):定义多个产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 系统需要独立于产品的创建、组合和表示时。
  • 系统需要使用多个产品族中的一个,且产品之间有依赖关系。
  • 需要动态切换产品系列时(如跨平台 UI、主题系统)。

代码示例

cpp 复制代码
// 抽象产品A
class AbstractProductA {
public:
    virtual void operationA() = 0;
    virtual ~AbstractProductA() = default;
};

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

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

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

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

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

// 抽象工厂
class AbstractFactory {
public:
    virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
    virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
    virtual ~AbstractFactory() = default;
};

// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
    std::unique_ptr<AbstractProductA> createProductA() override {
        return std::make_unique<ProductA1>();
    }
    
    std::unique_ptr<AbstractProductB> createProductB() override {
        return std::make_unique<ProductB1>();
    }
};

// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:
    std::unique_ptr<AbstractProductA> createProductA() override {
        return std::make_unique<ProductA2>();
    }
    
    std::unique_ptr<AbstractProductB> createProductB() override {
        return std::make_unique<ProductB2>();
    }
};

// 客户端使用
void client(AbstractFactory& factory) {
    auto productA = factory.createProductA();
    auto productB = factory.createProductB();
    productA->operationA();
    productB->operationB();
}

// 使用示例
int main() {
    ConcreteFactory1 factory1;
    client(factory1); // 输出: ProductA1::operationA() 和 ProductB1::operationB()
    
    ConcreteFactory2 factory2;
    client(factory2); // 输出: ProductA2::operationA() 和 ProductB2::operationB()
}

特点

  • 优点:将产品族的创建封装,保证产品间的兼容性;易于切换产品系列。
  • 缺点:新增产品族需修改抽象工厂及其所有子类,违反开闭原则;实现复杂。

四、三者对比总结

维度 简单工厂模式 工厂方法模式 抽象工厂模式
核心思想 将对象创建逻辑封装在一个工厂类中 定义创建对象的接口,由子类实现具体创建逻辑 提供创建一系列相关产品的接口,无需指定具体类
工厂数量 一个工厂类 一个抽象工厂和多个具体工厂 一个抽象工厂和多个具体工厂
产品数量 一个产品等级结构 一个产品等级结构 多个产品等级结构(产品族)
扩展性 新增产品需修改工厂类,违反开闭原则 新增产品只需添加新的具体工厂,符合开闭原则 新增产品族需修改抽象工厂,违反开闭原则
适用场景 产品种类少且创建逻辑简单 需要灵活扩展创建逻辑的场景 创建相互依赖的产品族的场景
复杂度 简单 中等 复杂

五、选择建议

  1. 优先使用简单工厂:当产品种类少且创建逻辑固定时。
  2. 使用工厂方法:当需要扩展性,且产品属于同一等级结构时。
  3. 使用抽象工厂:当需要创建多个相关产品,且产品间有依赖关系时。

在实际应用中,可根据需求灵活组合这些模式,例如在抽象工厂中使用工厂方法实现具体产品的创建,或使用简单工厂管理产品注册。


如果这篇文章对你有所帮助,渴望获得你的一个点赞!

相关推荐
我最厉害。,。5 小时前
C2远控篇&C&C++&ShellCode分离&File提取&Http协议&Argv参数&Sock管道
c语言·c++·http
Cyrus_柯5 小时前
C++(面向对象编程——关键字)
开发语言·c++·算法·面向对象
2013编程爱好者5 小时前
C++二分查找
开发语言·c++·算法·二分查找
叶子椰汁5 小时前
ORMPP链接MySQL 8.0错误
服务器·数据库·c++·mysql
十五年专注C++开发6 小时前
QSimpleUpdater:解锁 Qt 应用自动更新的全新姿势
开发语言·c++·qt
杰_happy6 小时前
设计模式:原型模式(C++)
c++·设计模式·原型模式
虾球xz7 小时前
CppCon 2016 学习:BUILDING A MODERN C++ FORGE FOR COMPUTE AND GRAPHICS
开发语言·c++·学习
老土豆FUSK8 小时前
C++ 引用的使用
开发语言·c++
achene_ql10 小时前
OpenCV C++ 图像处理教程:灰度变换与直方图分析
c++·图像处理·人工智能·opencv·计算机视觉