工厂模式核心是将new操作从调用方剥离,通过统一接口控制对象创建,实现创建逻辑集中化与编译依赖收敛;需返回智能指针的基类接口,调用方仅包含工厂和基类头文件。
工厂模式在 C++ 里不是靠“定义一个叫 Factory 的类”就完事的,核心是把 new 操作从调用方剥离,交由统一接口控制对象创建逻辑。直接 new 具体类,等于把耦合写死;用工厂,才能让新增子类不改已有代码。
为什么不能直接 new,而要用工厂函数或工厂类
硬编码 new Derived() 会让业务逻辑和具体类型强绑定。比如日志模块要支持 FileLogger、ConsoleLogger、NetLogger,如果每个地方都 new FileLogger,后续加个 DBLogger 就得翻遍所有 new 的位置改代码。
工厂解决的是「创建逻辑集中化」问题,不是语法炫技。常见错误是:只封装了 new,但没隔离类型依赖——比如工厂返回 Derived* 却要求调用方包含 Derived.h,那头文件依赖照样散开。
- 真正解耦的关键:工厂返回基类指针(如
std::unique_ptr),且调用方只 include 工厂头文件和基类声明 - 工厂内部才 include 具体子类头文件,实现编译依赖收敛
- 避免裸指针:优先用
std::unique_ptr或std::shared_ptr,防止资源泄漏
简单工厂:用 switch 或 map 实现创建逻辑
简单工厂不是 GoF 23 种之一,但最常用、最易理解。它本质是一个创建函数或静态方法,输入类型标识,输出对象指针。
立即学习“C++免费学习笔记(深入)”;
示例中用字符串标识比枚举更灵活(配置文件可读),但要注意大小写和拼写一致性:
std::unique_ptr createLogger(const std::string& type) {
if (type == "file") return std::make_unique();
if (type == "console") return std::make_unique();
if (type == "net") return std::make_unique();
throw std::runtime_error("Unknown logger type: " + type);
}
容易踩的坑: