工厂模式简介
工厂模式(Factory Pattern) 是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过使用 new
关键字直接实例化对象。工厂模式将对象的创建过程封装起来,使代码更灵活且易于扩展。工厂模式可以分为以下几种类型:
-
简单工厂模式(Simple Factory Pattern):并不属于 GoF(四人帮)设计模式中的一种,但也是一种常用的模式。简单工厂通过一个工厂类来决定实例化哪一个具体类,通常是通过传递参数来决定。
-
工厂方法模式(Factory Method Pattern):定义一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法使得类的实例化延迟到子类。
-
抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
下面我们主要讨论 工厂方法模式,并提供相关代码示例。
工厂方法模式
工厂方法模式 是一种设计模式,它定义了一个创建对象的接口,但允许子类决定实例化哪个类。工厂方法让类的实例化推迟到子类,这样代码的扩展性和灵活性就得到了提高。
关键点:
- 抽象产品类(Product):定义了工厂方法所创建的对象的接口。
- 具体产品类(ConcreteProduct):实现了抽象产品接口的具体类。
- 抽象工厂类(Creator):声明了返回对象的工厂方法。
- 具体工厂类(ConcreteCreator):实现了工厂方法,返回具体产品实例。
工厂方法模式的示例代码
假设我们需要创建一个关于不同类型日志记录器的系统,日志记录器可能是文件日志记录器、数据库日志记录器等。我们使用工厂方法模式来设计这个系统。
代码示例
cpp
#include <iostream>
#include <memory>
// 抽象产品类:日志记录器接口
class Logger {
public:
virtual void log(const std::string& message) = 0;
virtual ~Logger() {}
};
// 具体产品类:文件日志记录器
class FileLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Logging to a file: " << message << std::endl;
}
};
// 具体产品类:数据库日志记录器
class DatabaseLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Logging to a database: " << message << std::endl;
}
};
// 抽象工厂类:日志记录器工厂接口
class LoggerFactory {
public:
virtual std::unique_ptr<Logger> createLogger() = 0;
virtual ~LoggerFactory() {}
};
// 具体工厂类:文件日志记录器工厂
class FileLoggerFactory : public LoggerFactory {
public:
std::unique_ptr<Logger> createLogger() override {
return std::make_unique<FileLogger>();
}
};
// 具体工厂类:数据库日志记录器工厂
class DatabaseLoggerFactory : public LoggerFactory {
public:
std::unique_ptr<Logger> createLogger() override {
return std::make_unique<DatabaseLogger>();
}
};
// 客户端代码
int main() {
// 创建一个文件日志记录器工厂
std::unique_ptr<LoggerFactory> fileLoggerFactory = std::make_unique<FileLoggerFactory>();
// 通过工厂创建日志记录器
std::unique_ptr<Logger> logger = fileLoggerFactory->createLogger();
// 使用日志记录器记录信息
logger->log("File log message");
// 创建一个数据库日志记录器工厂
std::unique_ptr<LoggerFactory> dbLoggerFactory = std::make_unique<DatabaseLoggerFactory>();
// 通过工厂创建日志记录器
logger = dbLoggerFactory->createLogger();
// 使用日志记录器记录信息
logger->log("Database log message");
return 0;
}
代码分析
- Logger:抽象产品类,定义了日志记录器的接口。
- FileLogger 和 DatabaseLogger :具体产品类,实现了
Logger
接口的具体日志记录器。 - LoggerFactory:抽象工厂类,声明了创建日志记录器的工厂方法。
- FileLoggerFactory 和 DatabaseLoggerFactory:具体工厂类,实现了创建具体日志记录器的工厂方法。
优点:
- 可扩展性好:在新增日志记录器时,只需要添加新的具体产品类和对应的具体工厂类,而不需要修改已有代码,符合开闭原则。
- 封装性好:工厂方法将对象的创建过程封装在工厂类中,客户端不需要关心具体产品的创建过程。
适用场景:
- 当一个类不知道它需要创建的对象的具体类型时。
- 当一个类希望由其子类来指定它所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并希望将哪一个子类是委托类的职责局部化时。
工厂模式通过将对象的创建过程封装在工厂类中,使代码更易于扩展和维护,是设计模式中非常重要的一种。