工厂模式是一种创建型设计模式,核心思想是:将对象的创建逻辑与使用逻辑分离,通过专门的 “工厂类” 负责创建对象,客户端无需关心对象的具体创建细节(如构造函数参数、子类选择等),只需通过工厂获取实例。

它主要解决 “对象创建复杂、耦合度高” 的问题,常见有 3 种细分形式:简单工厂模式(入门)、工厂方法模式(解耦工厂与产品)、抽象工厂模式(多产品族创建)。

一、核心原理

1. 解决的问题

  • 客户端直接 new 对象会导致耦合度高(需知道具体类名、构造细节)。
  • 若对象创建逻辑复杂(如多子类选择、参数校验、初始化流程),直接写在客户端会冗余且难维护。
  • 需统一管理对象创建(如单例、池化、日志记录)。

2. 核心角色(通用)

角色职责
产品(Product)定义工厂要创建的对象的统一接口(或抽象类),是所有具体产品的基类。
具体产品(ConcreteProduct)实现产品接口的具体对象(如 “苹果手机”“华为手机”)。
工厂(Factory)负责创建产品的核心类,提供创建产品的方法(静态或实例方法),封装创建逻辑。

3. 设计关键

  • 面向接口编程:客户端依赖产品接口而非具体产品,工厂返回接口类型,降低耦合。
  • 封装创建逻辑:将 new 操作、子类选择、参数处理等放在工厂中,客户端仅调用工厂方法。

二、三种工厂模式的 C++ 实现

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

原理
  • 一个工厂类 + 一个产品接口 + 多个具体产品。
  • 工厂通过 “参数判断” 创建对应具体产品,客户端传入参数即可获取实例。
  • 优点:简单直观;缺点:工厂类与具体产品强耦合,新增产品需修改工厂代码(违反 “开闭原则”)。
示例:手机工厂(创建不同品牌手机)
#include <iostream>
#include <string>
using namespace std;

// 1. 产品接口(统一手机功能)
class Phone {
public:
    virtual ~Phone() = default; // 基类析构设为虚函数,避免内存泄漏
    virtual void showBrand() const = 0; // 纯虚函数:展示品牌
};

// 2. 具体产品1:苹果手机
class IPhone : public Phone {
public:
    void showBrand() const override {
        cout << "我是苹果手机(IPhone)" << endl;
    }
};

// 3. 具体产品2:华为手机
class HuaweiPhone : public Phone {
public:
    void showBrand() const override {
        cout << "我是华为手机(Huawei)" << endl;
    }
};

// 4. 简单工厂类(核心:根据参数创建产品)
class PhoneFactory {
public:
    // 静态工厂方法:传入品牌参数,返回对应手机实例
    static Phone* createPhone(const string& brand) {
        if (brand == "IPhone") {
            return new IPhone();
        } else if (brand == "Huawei") {
            return new HuaweiPhone();
        } else {
            cout << "不支持的手机品牌!" << endl;
            return nullptr;
        }
    }
};

// 客户端使用
int main() {
    // 客户端无需知道 IPhone/HuaweiPhone 的创建细节,仅调用工厂方法
    Phone* phone1 = PhoneFactory::createPhone("IPhone");
    if (phone1) {
        phone1->showBrand(); // 输出:我是苹果手机(IPhone)
        delete phone1;
    }

    Phone* phone2 = PhoneFactory::createPhone("Huawei");
    if (phone2) {
        phone2->showBrand(); // 输出:我是华为手机(Huawei)
        delete phone2;
    }

    Phone* phone3 = PhoneFactory::createPhone("Xiaomi"); // 输出:不支持的手机品牌!
    delete phone3;

    return 0;
}

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

原理
  • 一个产品接口 + 多个具体产品 + 一个工厂接口 + 多个具体工厂(每个具体产品对应一个具体工厂)。
  • 工厂接口定义创建产品的方法,具体工厂实现该方法创建对应产品。
  • 优点:遵循 “开闭原则”,新增产品只需新增具体产品类和具体工厂类,无需修改原有代码;缺点:类数量增多(产品和工厂一一对应)。
示例:手机工厂(每个品牌对应专属工厂)
#include <iostream>
#include <string>
using namespace std;

// 1. 产品接口(与简单工厂一致)
class Phone {
public:
    virtual ~Phone() = default;
    virtual void showBrand() const = 0;
};

// 2. 具体产品(与简单工厂一致)
class IPhone : public Phone {
public:
    void showBrand() const override { cout << "我是苹果手机(IPhone)" << endl; }
};

class HuaweiPhone : public Phone {
public:
    void showBrand() const override { cout << "我是华为手机(Huawei)" << endl; }
};

// 3. 工厂接口(定义创建产品的方法)
class PhoneFactory {
public:
    virtual ~PhoneFactory() = default;
    virtual Phone* createPhone() const = 0; // 纯虚函数:创建手机(具体由子类实现)
};

// 4. 具体工厂1:苹果工厂(仅创建苹果手机)
class IPhoneFactory : public PhoneFactory {
public:
    Phone* createPhone() const override {
        return new IPhone();
    }
};

// 5. 具体工厂2:华为工厂(仅创建华为手机)
class HuaweiFactory : public PhoneFactory {
public:
    Phone* createPhone() const override {
        return new HuaweiPhone();
    }
};

// 客户端使用
int main() {
    // 要创建苹果手机:实例化苹果工厂,调用工厂方法
    PhoneFactory* factory1 = new IPhoneFactory();
    Phone* phone1 = factory1->createPhone();
    phone1->showBrand(); // 输出:我是苹果手机(IPhone)
    delete phone1;
    delete factory1;

    // 要创建华为手机:实例化华为工厂,调用工厂方法
    PhoneFactory* factory2 = new HuaweiFactory();
    Phone* phone2 = factory2->createPhone();
    phone2->showBrand(); // 输出:我是华为手机(Huawei)
    delete phone2;
    delete factory2;

    return 0;
}

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

原理
  • 多个产品接口(产品族) + 多个具体产品族 + 一个抽象工厂接口 + 多个具体工厂(每个工厂负责一个产品族的创建)。
  • 核心是 “产品族”:一组相关联的产品(如 “苹果手机 + 苹果电脑”“华为手机 + 华为电脑”)。
  • 优点:统一创建产品族,保证产品兼容性;缺点:新增产品族需修改抽象工厂接口(违反 “开闭原则”),适合产品族稳定的场景。
示例:电子设备工厂(创建手机 + 电脑的产品族)
#include <iostream>
#include <string>
using namespace std;

// -------------------------- 产品族接口 --------------------------
// 产品1接口:手机
class Phone {
public:
    virtual ~Phone() = default;
    virtual void showBrand() const = 0;
};

// 产品2接口:电脑
class Computer {
public:
    virtual ~Computer() = default;
    virtual void showBrand() const = 0;
};

// -------------------------- 具体产品族1:苹果系列 --------------------------
class IPhone : public Phone {
public:
    void showBrand() const override { cout << "苹果手机(IPhone 15)" << endl; }
};

class MacBook : public Computer {
public:
    void showBrand() const override { cout << "苹果电脑(MacBook Pro)" << endl; }
};

// -------------------------- 具体产品族2:华为系列 --------------------------
class HuaweiPhone : public Phone {
public:
    void showBrand() const override { cout << "华为手机(Mate 60)" << endl; }
};

class HuaweiPC : public Computer {
public:
    void showBrand() const override { cout << "华为电脑(MateBook X Pro)" << endl; }
};

// -------------------------- 抽象工厂接口(定义产品族的创建方法) --------------------------
class ElectronicFactory {
public:
    virtual ~ElectronicFactory() = default;
    virtual Phone* createPhone() const = 0;     // 创建手机
    virtual Computer* createComputer() const = 0; // 创建电脑
};

// -------------------------- 具体工厂1:苹果工厂(创建苹果产品族) --------------------------
class AppleFactory : public ElectronicFactory {
public:
    Phone* createPhone() const override {
        return new IPhone();
    }
    Computer* createComputer() const override {
        return new MacBook();
    }
};

// -------------------------- 具体工厂2:华为工厂(创建华为产品族) --------------------------
class HuaweiFactory : public ElectronicFactory {
public:
    Phone* createPhone() const override {
        return new HuaweiPhone();
    }
    Computer* createComputer() const override {
        return new HuaweiPC();
    }
};

// 客户端使用
int main() {
    // 1. 购买苹果产品族
    ElectronicFactory* appleFactory = new AppleFactory();
    Phone* iphone = appleFactory->createPhone();
    Computer* mac = appleFactory->createComputer();
    cout << "苹果产品族:" << endl;
    iphone->showBrand();  // 输出:苹果手机(IPhone 15)
    mac->showBrand();     // 输出:苹果电脑(MacBook Pro)
    delete iphone;
    delete mac;
    delete appleFactory;

    // 2. 购买华为产品族
    ElectronicFactory* huaweiFactory = new HuaweiFactory();
    Phone* huaweiPhone = huaweiFactory->createPhone();
    Computer* huaweiPC = huaweiFactory->createComputer();
    cout << "\n华为产品族:" << endl;
    huaweiPhone->showBrand(); // 输出:华为手机(Mate 60)
    huaweiPC->showBrand();    // 输出:华为电脑(MateBook X Pro)
    delete huaweiPhone;
    delete huaweiPC;
    delete huaweiFactory;

    return 0;
}

输出结果:

苹果产品族:
苹果手机(IPhone 15)
苹果电脑(MacBook Pro)

华为产品族:
华为手机(Mate 60)
华为电脑(MateBook X Pro)

三、三种工厂模式的对比与选择

模式类型核心特点优点缺点适用场景
简单工厂模式一个工厂创建所有产品(参数判断)代码简单,客户端使用便捷违反开闭原则,新增产品需修改工厂产品数量少、变化少(如工具类创建)
工厂方法模式产品与工厂一一对应(工厂接口 + 具体工厂)遵循开闭原则,扩展灵活类数量增多(产品 + 工厂)产品数量较多、需频繁扩展(如插件系统)
抽象工厂模式一个工厂创建一个产品族(多产品接口)保证产品族兼容性,统一创建逻辑新增产品族需修改抽象工厂接口需创建一组相关联的产品(如软硬件套装)

四、关键注意事项

  1. 内存管理:示例中用裸指针创建对象,实际开发中建议使用 std::unique_ptr/std::shared_ptr 智能指针,避免内存泄漏(如 return std::make_unique<IPhone>())。
  2. 接口一致性:产品类需继承统一接口,工厂方法返回接口类型,确保客户端可统一使用。
  3. 避免过度设计:若产品简单(无多子类、创建逻辑简单),直接 new 即可,无需强行使用工厂模式。
  4. 线程安全:若工厂方法是静态的或全局工厂,多线程环境下需注意创建逻辑的线程安全(如加锁、使用原子操作)。

五、总结

工厂模式的核心价值是 “分离对象的创建与使用”:

  • 降低耦合:客户端无需依赖具体产品类,仅依赖工厂和产品接口。
  • 便于维护:对象创建逻辑集中在工厂,修改时只需改工厂代码。
  • 灵活扩展:根据业务场景选择不同工厂模式(简单工厂适合简单场景,工厂方法 / 抽象工厂适合复杂场景)。

它是实际开发中最常用的设计模式之一,例如框架中的对象创建(如 Spring 的 BeanFactory)、插件系统、配置化创建对象等场景都有广泛应用。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐