工厂方法模式属于创建型设计模式的一种,它的核心目的是将对象的创建逻辑封装到独立的工厂类中,让客户端代码不需要直接依赖具体产品的实现类,只需要通过抽象的工厂接口获取对应的产品实例,从而提升代码的可维护性和扩展性。
工厂方法模式的核心结构
工厂方法模式通常包含四个核心角色,每个角色的职责划分非常清晰:
- 抽象产品(Product):定义所有具体产品需要实现的公共接口,是产品的抽象基类。
- 具体产品(ConcreteProduct):实现抽象产品接口的具体类,对应实际需要创建的对象。
- 抽象工厂(Factory):声明创建抽象产品的纯虚函数,是所有工厂类的基类。
- 具体工厂(ConcreteFactory):继承抽象工厂,实现创建具体产品的逻辑,每个具体工厂对应一个具体产品。
基础实现示例
下面以日志输出场景为例,实现不同日志类型(控制台日志、文件日志)的工厂创建逻辑,首先定义抽象产品和具体产品:
// 抽象产品:日志接口
class Logger {
public:
virtual ~Logger() {}
// 输出日志的纯虚函数
virtual void log(const std::string& message) = 0;
};
// 具体产品:控制台日志
class ConsoleLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "控制台日志: " << message << std::endl;
}
};
// 具体产品:文件日志
class FileLogger : public Logger {
public:
void log(const std::string& message) override {
// 实际场景中会实现文件写入逻辑,这里简化为输出提示
std::cout << "文件日志: " << message << std::endl;
}
};
接下来定义抽象工厂和对应的具体工厂:
// 抽象工厂:日志工厂接口
class LoggerFactory {
public:
virtual ~LoggerFactory() {}
// 创建日志对象的纯虚函数
virtual Logger* createLogger() = 0;
};
// 具体工厂:控制台日志工厂
class ConsoleLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new ConsoleLogger();
}
};
// 具体工厂:文件日志工厂
class FileLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new FileLogger();
}
};
客户端代码使用时,只需要依赖抽象工厂和抽象产品,不需要直接创建具体产品实例:
#include <iostream>
#include <string>
// 上面的类和接口定义放在这里
int main() {
// 使用控制台日志工厂创建实例
LoggerFactory* consoleFactory = new ConsoleLoggerFactory();
Logger* consoleLogger = consoleFactory->createLogger();
consoleLogger->log("这是一条测试日志");
// 使用文件日志工厂创建实例
LoggerFactory* fileFactory = new FileLoggerFactory();
Logger* fileLogger = fileFactory->createLogger();
fileLogger->log("这是另一条测试日志");
// 释放资源
delete consoleLogger;
delete consoleFactory;
delete fileLogger;
delete fileFactory;
return 0;
}
结合代码重构的应用场景
如果现有代码中已经存在大量直接通过new创建具体产品实例的逻辑,会导致客户端代码和具体产品强耦合,后续新增产品类型时需要修改大量客户端代码。这时候可以通过工厂方法模式进行重构:
重构前的耦合代码
假设原来的代码直接在业务逻辑中创建日志对象:
// 重构前的代码,直接依赖具体产品
void oldBusinessLogic() {
// 直接创建控制台日志实例
Logger* logger = new ConsoleLogger();
logger->log("执行业务逻辑");
delete logger;
}
重构后的解耦代码
引入工厂方法后,业务逻辑只需要接收工厂对象,不需要关心具体产品的创建细节:
// 重构后的业务逻辑,依赖抽象工厂
void newBusinessLogic(LoggerFactory* factory) {
Logger* logger = factory->createLogger();
logger->log("执行业务逻辑");
delete logger;
}
如果后续需要新增网络日志类型,只需要新增NetworkLogger类和NetworkLoggerFactory类,不需要修改newBusinessLogic函数的代码,符合开闭原则。
注意事项
- 工厂方法模式适合产品类型会频繁扩展的场景,如果产品类型非常固定,使用简单工厂模式会更简洁。
- 实际开发中建议结合智能指针管理对象生命周期,避免手动释放内存带来的泄漏风险,可以将工厂的返回类型改为
std::unique_ptr<Logger>。 - 抽象产品和抽象工厂的设计要尽量稳定,避免频繁修改接口导致所有子类都需要调整。
工厂方法模式的核心是让对象的创建延迟到子类完成,通过抽象层隔离客户端和具体实现的依赖,是降低代码耦合度的有效手段。
C++_factory_method设计模式代码重构面向对象编程修改时间:2026-06-28 01:27:37