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

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

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

定义与结构

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

适用场景

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

代码示例

// 抽象产品
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):实现抽象产品接口。

适用场景

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

代码示例

// 抽象产品
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、主题系统)。

代码示例

// 抽象产品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. 使用抽象工厂:当需要创建多个相关产品,且产品间有依赖关系时。

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


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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

OpenC++

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

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

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

打赏作者

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

抵扣说明:

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

余额充值