Logic / 一:简单工厂模式--极简教程

Created Mon, 22 Sep 2025 22:43:32 +0800 Modified Sat, 18 Oct 2025 01:48:04 +0800

简单工厂

类图如下

特征 简单工厂 工厂方法 抽象工厂
工厂类结构 一个具体类 抽象类 + 多个具体子类 抽象类 + 多个具体子类,每个子类创建一组相关对象
创建逻辑 集中在工厂类中 分散在各个具体工厂中 分散在各个具体工厂中,每个工厂创建完整的产品族
扩展性 需要修改工厂类 添加新产品需添加新工厂子类 添加新产品族需添加新工厂子类,添加新产品类型需要修改抽象接口
符合开闭原则 是(对扩展开放) 是(对产品族扩展开放,对产品类型修改关闭)
主要目的 封装对象创建逻辑 将对象创建延迟到子类 创建相关或依赖对象家族
产品关系 单一产品层次 单一产品层次 多个相关产品层次(产品族)
使用场景 产品类型少且稳定 产品类型可能扩展 需要创建整套相关产品

代码实现

引入动态注册

  • 为了符合开闭原则,我们使用注册型工厂,将具体产品的创建函数注册到工厂中 RegisteredFactory.cpp
class RegisteredFactory {
public:
    using Creator = std::function<std::unique_ptr<Shape>()>;
    
    static void registerShape(const std::string& type, Creator creator) {
        auto& registry = getRegistry();
        registry[type] = creator;
    }
    
    static std::unique_ptr<Shape> create(const std::string& type) {
        auto& registry = getRegistry();
        auto it = registry.find(type);
        if (it != registry.end()) {
            return it->second();
        }
        return nullptr;
    }
    
    static bool isRegistered(const std::string& type) {
        auto& registry = getRegistry();
        return registry.find(type) != registry.end();
    }

private:
    static std::map<std::string, Creator>& getRegistry() {
        static std::map<std::string, Creator> registry;
        return registry;
    }
};

client.cpp

   int main(){
       // 注册创建器
        RegisteredFactory::registerShape("circle", []() {
            return std::make_unique<Circle>();
        });
        
        RegisteredFactory::registerShape("rectangle", []() {
            return std::make_unique<Rectangle>();
        });
        
        // 使用注册的工厂
        auto regCircle = RegisteredFactory::create("circle");
        auto regRectangle = RegisteredFactory::create("rectangle");
   }
   

这里客户端代码仍然不满足开闭原则,因此,进一步的,引入静态注册

静态注册

使用宏定义 RegisteredFactory.cpp

    #include <iostream>
#include <memory>
#include <string>
#include <map>
#include <functional>

// 产品基类
class Shape {
public:
    virtual ~Shape() = default;
    virtual void draw() const = 0;
    virtual std::unique_ptr<Shape> clone() const = 0;
    virtual std::string typeName() const = 0;
};

// 注册式工厂
class RegisteredFactory {
public:
    using Creator = std::function<std::unique_ptr<Shape>()>;
    
    static void registerShape(const std::string& type, Creator creator) {
        auto& registry = getRegistry();
        registry[type] = creator;
    }
    
    static std::unique_ptr<Shape> create(const std::string& type) {
        auto& registry = getRegistry();
        auto it = registry.find(type);
        if (it != registry.end()) {
            return it->second();
        }
        return nullptr;
    }
    
    static bool isRegistered(const std::string& type) {
        auto& registry = getRegistry();
        return registry.find(type) != registry.end();
    }
    
    static void listRegisteredTypes() {
        auto& registry = getRegistry();
        std::cout << "Registered types: ";
        for (const auto& [type, _] : registry) {
            std::cout << type << " ";
        }
        std::cout << std::endl;
    }

private:
    static std::map<std::string, Creator>& getRegistry() {
        static std::map<std::string, Creator> registry;
        return registry;
    }
};

// 宏定义:自动注册形状类
#define REGISTER_SHAPE(TYPE, CLASS) \
    namespace { \
        class CLASS##Registrar { \
        public: \
            CLASS##Registrar() { \
                RegisteredFactory::registerShape(TYPE, []() { \
                    return std::make_unique<CLASS>(); \
                }); \
                std::cout << "[MACRO] Registered: " << TYPE << " -> " << #CLASS << std::endl; \
            } \
        }; \
        CLASS##Registrar CLASS##_registrar; \
    }

// 带参数的扩展宏
#define REGISTER_SHAPE_WITH_ARGS(TYPE, CLASS, ...) \
    namespace { \
        class CLASS##Registrar { \
        public: \
            CLASS##Registrar() { \
                RegisteredFactory::registerShape(TYPE, []() { \
                    return std::make_unique<CLASS>(__VA_ARGS__); \
                }); \
                std::cout << "[MACRO] Registered: " << TYPE << " -> " << #CLASS << " with args" << std::endl; \
            } \
        }; \
        CLASS##Registrar CLASS##_registrar; \
    }

定义具体的产品类,并进行静态注册 Circle.h

// 具体形状类定义
class Circle : public Shape {
private:
    double m_radius;
    
public:
    Circle() : m_radius(1.0) {}
    explicit Circle(double radius) : m_radius(radius) {}
    
    void draw() const override {
        std::cout << "Drawing Circle with radius: " << m_radius << std::endl;
    }
    
    std::unique_ptr<Shape> clone() const override {
        return std::make_unique<Circle>(*this);
    }
    
    std::string typeName() const override {
        return "circle";
    }
};
REGISTER_SHAPE("circle", Circle)

Rectangle.h

// 使用宏自动注册
class Rectangle : public Shape {
private:
    double width_, height_;
    
public:
    Rectangle() : width_(1.0), height_(1.0) {}
    Rectangle(double width, double height) : width_(width), height_(height) {}
    
    void draw() const override {
        std::cout << "Drawing Rectangle " << width_ << "x" << height_ << std::endl;
    }
    
    std::unique_ptr<Shape> clone() const override {
        return std::make_unique<Rectangle>(*this);
    }
    
    std::string typeName() const override {
        return "rectangle";
    }
};

// 使用带参数的注册宏
REGISTER_SHAPE_WITH_ARGS("rectangle", Rectangle, 2.0, 3.0)

client.cpp

    // 列出所有已注册的类型
   auto typeList =  RegisteredFactory::listRegisteredTypes();
   for(auto type:typeList){
        auto shape = RegisteredFactory::create(type);
   }

原理解析

C++程序执行阶段

程序启动
↓
静态存储期对象构造 (静态初始化阶段)
↓
main() 函数开始执行
↓
程序逻辑执行
↓
main() 函数结束
↓
静态存储期对象析构

宏展开后,定义了一个全局对象,会在main函数执行前进行创建

// 原始宏调用
REGISTER_SHAPE("circle", Circle)

// 宏展开后的代码
namespace {
    class CircleRegistrar {
    public:
        CircleRegistrar() {
            RegisteredFactory::registerShape("circle", []() {
                return std::make_unique<Circle>();
            });
            std::cout << "[MACRO] Registered: circle -> Circle" << std::endl;
        }
    };
    CircleRegistrar Circle_registrar;  // ← 关键在这里!
}