23种设计模式-工厂方法(Factory Method)设计模式

文章目录

类图: 工厂方法设计模式类图

一.什么是工厂方法设计模式?

工厂方法模式 (Factory Method Pattern) 是一种创建型设计模式,它定义了一个创建对象的接口,由子类决定要实例化的具体类。工厂方法模式让类的实例化延迟到子类,从而避免了直接在代码中使用 new 关键字实例化具体类。

二. 工厂方法模式的特点

  • 解耦:将对象的创建与使用分离,降低耦合性。
  • 可扩展性强:可以通过新增具体产品类和具体工厂类来扩展产品族,而无需修改现有代码。
  • 遵循开闭原则:对扩展开放,对修改封闭。

三.工厂方法模式的结构

  • Product(抽象产品类):定义产品的接口,具体产品需要实现此接口。
  • ConcreteProduct(具体产品类):实现抽象产品接口,定义产品的具体实现。
  • Creator(抽象工厂类):定义一个创建产品对象的抽象方法。
  • ConcreteCreator(具体工厂类) :实现工厂方法,负责创建具体产品对象。

四.工厂方法模式的优缺点

  • 优点:
    • 减少耦合:客户端通过工厂方法与具体产品类解耦。
    • 扩展性强:通过增加新的具体工厂和产品类来支持新功能。
    • 符合设计原则:遵循单一职责和开闭原则。
  • 缺点:
    • 增加复杂性:需要为每种具体产品创建对应的工厂类,类的数量增加。
    • 限制适用场景:工厂方法适合创建少量的产品,如果产品种类非常多,代码复杂度会增加。

五.工厂方法模式的 C++ 实现

cpp 复制代码
#include <iostream>
#include <memory>
using namespace std;

// 抽象产品类
class Product {
public:
    virtual void UseProduct() = 0; // 使用产品的接口
    virtual ~Product() = default;
};

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

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

// 抽象工厂类
class Creator {
public:
    virtual unique_ptr<Product> FactoryMethod() = 0; // 工厂方法
    virtual ~Creator() = default;
};

// 具体工厂A
class ConcreteCreatorA : public Creator {
public:
    unique_ptr<Product> FactoryMethod() override {
        return make_unique<ConcreteProductA>(); // 创建具体产品A
    }
};

// 具体工厂B
class ConcreteCreatorB : public Creator {
public:
    unique_ptr<Product> FactoryMethod() override {
        return make_unique<ConcreteProductB>(); // 创建具体产品B
    }
};

// 测试代码
int main() {
    unique_ptr<Creator> factoryA = make_unique<ConcreteCreatorA>();
    unique_ptr<Product> productA = factoryA->FactoryMethod();
    productA->UseProduct();

    unique_ptr<Creator> factoryB = make_unique<ConcreteCreatorB>();
    unique_ptr<Product> productB = factoryB->FactoryMethod();
    productB->UseProduct();

    return 0;
}

六.工厂方法模式的 Java 实现

java 复制代码
// 抽象产品类
interface Product {
    void useProduct(); // 使用产品的接口
}

// 具体产品A
class ConcreteProductA implements Product {
    public void useProduct() {
        System.out.println("Using ConcreteProductA");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void useProduct() {
        System.out.println("Using ConcreteProductB");
    }
}

// 抽象工厂类
abstract class Creator {
    public abstract Product factoryMethod(); // 工厂方法
}

// 具体工厂A
class ConcreteCreatorA extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductA(); // 创建具体产品A
    }
}

// 具体工厂B
class ConcreteCreatorB extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductB(); // 创建具体产品B
    }
}

// 测试代码
public class FactoryMethodDemo {
    public static void main(String[] args) {
        Creator factoryA = new ConcreteCreatorA();
        Product productA = factoryA.factoryMethod();
        productA.useProduct();

        Creator factoryB = new ConcreteCreatorB();
        Product productB = factoryB.factoryMethod();
        productB.useProduct();
    }
}

七.代码解析

  1. 抽象产品类
    • Product 定义了一个抽象接口 UseProduct,所有具体产品类都必须实现此接口。
    • 通过多态,客户端代码无需关心具体产品类的类型,只需调用接口方法。
  2. 具体产品类
    • ConcreteProductA 和 ConcreteProductB 是 Product 的派生类,分别实现了 UseProduct 接口。
    • 每个具体产品类有自己的实现逻辑,例如打印不同的消息。
  3. 抽象工厂类
    • Creator 定义了一个纯虚函数 FactoryMethod,用于创建产品。
    • 通过将工厂方法定义为虚函数,使得子类可以重写以返回不同的具体产品实例。
  4. 具体工厂类
    • ConcreteCreatorA 和 ConcreteCreatorB 是 Creator 的派生类,分别重写了 FactoryMethod。
    • FactoryMethod 返回具体产品类的实例,这里使用了 C++11 的 unique_ptr 智能指针,避免了手动管理内存的复杂性。
  5. 客户端代码
    • main 函数中,首先创建工厂对象(如 ConcreteCreatorA),通过工厂对象调用 FactoryMethod 方法获取产品实例。
    • 调用产品的 UseProduct 方法进行操作。
    • 使用 unique_ptr 确保资源自动释放,无需手动销毁。

八.总结

工厂方法模式是一种灵活的创建对象模式,适用于需要根据不同条件创建多种产品实例的场景。C++ 的实现中通过继承和多态实现工厂方法,同时使用智能指针避免了内存泄漏的问题。Java 的实现通过抽象类和具体类的组合也达到了类似效果。虽然工厂方法模式提高了代码的灵活性,但也增加了系统的复杂性,需要根据项目实际需求合理使用。
应用场景:

  • 需要灵活创建对象:如日志记录器可以根据配置创建文件日志或数据库日志实例。
  • 避免依赖具体类:如多种数据库连接类型,可以通过工厂方法动态生成。
  • 需要控制对象创建逻辑:如只允许创建特定种类的实例。
相关推荐
小王努力学编程33 分钟前
高并发内存池(三):TLS无锁访问以及Central Cache结构设计
jvm·数据结构·c++·学习
周努力.2 小时前
设计模式之中介者模式
设计模式·中介者模式
字节高级特工3 小时前
【C++】”如虎添翼“:模板初阶
java·c语言·前端·javascript·c++·学习·算法
.Vcoistnt3 小时前
Codeforces Round 1024 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划·图论
越甲八千3 小时前
MFC listctrl修改背景颜色
c++·mfc
炯哈哈3 小时前
【上位机——MFC】序列化机制
开发语言·c++·mfc·上位机
隐世13 小时前
C++多态讲解
开发语言·c++
Wooden-Flute3 小时前
十四、继承与组合(Inheritance & Composition)
c++
阳区欠3 小时前
【Linux】线程的同步与互斥
linux·服务器·c++·线程同步·线程互斥·生产者/消费者模型
格鸰爱童话3 小时前
软考错题(三)
软考