当前位置: 首页 > news >正文

设计模式 | 工厂模式

工厂模式(Factory Pattern) 是创建型设计模式的核心成员,它通过将对象创建的逻辑封装起来,实现了创建与使用的解耦。本文将深入探讨工厂模式的核心思想、实现技巧以及在C++中的高效实现方式。

为什么需要工厂模式?

在软件开发中,直接使用new关键字创建对象会带来诸多问题:

  • 紧耦合:客户端代码依赖具体类实现

  • 难以扩展:添加新产品需要修改客户端代码

  • 职责混乱:对象创建逻辑分散在各处

  • 违反开闭原则:对修改开放,对扩展封闭

工厂模式通过封装对象创建过程解决了这些问题,提供了一种灵活的创建机制。当你的代码中存在以下情况时,工厂模式特别有用:

  • 无法预知需要创建的具体类型

  • 需要集中管理对象的创建逻辑

  • 系统需要支持多种类型的产品

  • 希望将实例化延迟到子类

工厂模式的两种形态

1. 简单工厂模式(静态工厂)

简单工厂模式是最基础的形式,它通过一个静态方法封装对象的创建逻辑。

#include <iostream>
#include <memory>
#include <stdexcept>// 抽象产品类:图形接口
class Shape {
public:virtual void draw() const = 0;virtual ~Shape() = default;
};// 具体产品类:圆形
class Circle : public Shape {
public:void draw() const override {std::cout << "○ 绘制圆形" << std::endl;}
};// 具体产品类:矩形
class Rectangle : public Shape {
public:void draw() const override {std::cout << "□ 绘制矩形" << std::endl;}
};// 具体产品类:三角形
class Triangle : public Shape {
public:void draw() const override {std::cout << "△ 绘制三角形" << std::endl;}
};// 简单工厂类
class ShapeFactory {
public:// 形状类型枚举enum ShapeType { CIRCLE, RECTANGLE, TRIANGLE };// 创建形状的静态方法static std::unique_ptr<Shape> createShape(ShapeType type) {switch (type) {case CIRCLE:return std::make_unique<Circle>();case RECTANGLE:return std::make_unique<Rectangle>();case TRIANGLE:return std::make_unique<Triangle>();default:throw std::invalid_argument("错误:不支持的形状类型");}}
};// 创建具体实列
int main() {// 创建圆形auto circle = ShapeFactory::createShape(ShapeFactory::CIRCLE);circle->draw();// 创建矩形auto rect = ShapeFactory::createShape(ShapeFactory::RECTANGLE);rect->draw();// 创建三角形auto triangle = ShapeFactory::createShape(ShapeFactory::TRIANGLE);triangle->draw();return 0;
}

优点

  • 实现简单,易于理解

  • 集中管理对象的创建逻辑

  • 客户端与具体产品类解耦

缺点

  • 违反开闭原则(添加新产品需修改工厂类)

  • 工厂类职责过重(所有产品都在一个工厂中创建)

  • 不支持运行时动态扩展

2. 工厂方法模式

工厂方法模式将对象创建延迟到子类,解决了简单工厂的开闭原则问题。

#include <iostream>
#include <memory>
#include <vector>// 抽象产品:日志记录器
class Logger {
public:virtual void log(const std::string& message) = 0;virtual ~Logger() = default;
};// 具体产品:文件日志
class FileLogger : public Logger {
public:void log(const std::string& message) override {std::cout << "[文件日志] " << message << std::endl;}
};// 具体产品:控制台日志
class ConsoleLogger : public Logger {
public:void log(const std::string& message) override {std::cout << "[控制台日志] " << message << std::endl;}
};// 具体产品:网络日志
class NetworkLogger : public Logger {
public:void log(const std::string& message) override {std::cout << "[网络日志] " << message << std::endl;}
};// 抽象创建者
class LoggerCreator {
public:virtual std::unique_ptr<Logger> createLogger() = 0;void logMessage(const std::string& message) {auto logger = createLogger();logger->log(message);}virtual ~LoggerCreator() = default;
};// 具体创建者:文件日志工厂
class FileLoggerCreator : public LoggerCreator {
public:std::unique_ptr<Logger> createLogger() override {return std::make_unique<FileLogger>();}
};// 具体创建者:控制台日志工厂
class ConsoleLoggerCreator : public LoggerCreator {
public:std::unique_ptr<Logger> createLogger() override {return std::make_unique<ConsoleLogger>();}
};// 具体创建者:网络日志工厂
class NetworkLoggerCreator : public LoggerCreator {
public:std::unique_ptr<Logger> createLogger() override {return std::make_unique<NetworkLogger>();}
};// 创建实例
int main() {std::vector<std::unique_ptr<LoggerCreator>> creators;creators.push_back(std::make_unique<FileLoggerCreator>());creators.push_back(std::make_unique<ConsoleLoggerCreator>());creators.push_back(std::make_unique<NetworkLoggerCreator>());for (auto& creator : creators) {creator->logMessage("应用启动完成");}return 0;
}

核心思想

  • 定义创建对象的接口,但让子类决定实例化哪个类

  • 工厂方法使一个类的实例化延迟到其子类

  • 符合"开闭原则" - 对扩展开放,对修改关闭

工厂方法模式的高级应用

1. 参数化工厂方法

class UniversalCreator : public LoggerCreator {
public:enum LoggerType { FILE, CONSOLE, NETWORK };UniversalCreator(LoggerType type) : type_(type) {}std::unique_ptr<Logger> createLogger() override {switch (type_) {case FILE: return std::make_unique<FileLogger>();case CONSOLE: return std::make_unique<ConsoleLogger>();case NETWORK: return std::make_unique<NetworkLogger>();default: throw std::invalid_argument("无效的日志类型");}}private:LoggerType type_;
};// 使用示例
int main() {UniversalCreator fileCreator(UniversalCreator::FILE);fileCreator.logMessage("保存到文件");UniversalCreator consoleCreator(UniversalCreator::CONSOLE);consoleCreator.logMessage("输出到控制台");return 0;
}

2. 工厂方法 + 单例模式

class Database {
public:virtual void connect() = 0;virtual ~Database() = default;
};class MySQL : public Database {
public:void connect() override {std::cout << "连接到MySQL数据库" << std::endl;}static MySQL& getInstance() {static MySQL instance;return instance;}private:MySQL() = default;
};class PostgreSQL : public Database {
public:void connect() override {std::cout << "连接到PostgreSQL数据库" << std::endl;}static PostgreSQL& getInstance() {static PostgreSQL instance;return instance;}private:PostgreSQL() = default;
};class DatabaseFactory {
public:virtual Database& create() = 0;virtual ~DatabaseFactory() = default;
};class MySQLFactory : public DatabaseFactory {
public:Database& create() override {return MySQL::getInstance();}
};class PostgreSQLFactory : public DatabaseFactory {
public:Database& create() override {return PostgreSQL::getInstance();}
};// 使用示例
int main() {MySQLFactory mysqlFactory;auto& mysql = mysqlFactory.create();mysql.connect();PostgreSQLFactory pgFactory;auto& pg = pgFactory.create();pg.connect();return 0;
}

工厂模式的优缺点分析

优点

  • 解耦创建者和具体产品

  • 符合开闭原则,易于扩展

  • 单一职责原则(创建逻辑集中)

  • 便于代码维护和测试

  • 支持依赖倒置原则

缺点

  • 引入额外类,增加系统复杂性

  • 需要设计良好的继承体系

  • 客户端可能需要理解工厂结构

  • 简单场景下可能显得过度设计

工厂模式的典型应用场景

  1. 框架设计:框架需要为应用提供扩展点

    class Plugin {
    public:virtual void execute() = 0;virtual ~Plugin() = default;
    };class PluginFactory {
    public:virtual std::unique_ptr<Plugin> createPlugin() = 0;
    };
  2. 跨平台开发:为不同平台创建适配对象

    class GUIButton {
    public:virtual void render() = 0;
    };class WindowsButton : public GUIButton { /*...*/ };
    class MacButton : public GUIButton { /*...*/ };class GUIFactory {
    public:virtual std::unique_ptr<GUIButton> createButton() = 0;
    };
  3. 对象池管理:管理可重用对象的创建

    class Connection {
    public:virtual void open() = 0;
    };class ConnectionPool {
    public:virtual std::unique_ptr<Connection> createConnection() = 0;virtual void returnConnection(std::unique_ptr<Connection>) = 0;
    };
  4. 依赖注入:通过工厂注入依赖对象

    class Service {
    public:virtual void performTask() = 0;
    };class Client {
    public:Client(std::unique_ptr<ServiceFactory> factory): factory_(std::move(factory)) {}void execute() {auto service = factory_->createService();service->performTask();}private:std::unique_ptr<ServiceFactory> factory_;
    };

工厂模式的最佳实践

  1. 优先使用工厂方法:除非系统非常简单,否则优先选择工厂方法模式

  2. 结合智能指针:使用std::unique_ptrstd::shared_ptr管理对象生命周期

  3. 使用模板减少重复代码

    template <typename T>
    class StandardCreator : public LoggerCreator {
    public:std::unique_ptr<Logger> createLogger() override {return std::make_unique<T>();}
    };// 使用
    StandardCreator<FileLogger> fileCreator;
  4. 工厂方法命名规范

  • createXXX()

  • makeXXX()

  • newXXX()

  • getInstance() (单例场景)

工厂模式 vs 简单工厂

特性简单工厂模式工厂方法模式
开闭原则违反(修改工厂类)支持(扩展子类)
复杂度简单中等
扩展性有限优秀
类数量较少较多(每个产品对应工厂)
适用场景产品类型少且固定产品类型多或可能扩展

总结

工厂模式是C++开发中强大的对象创建工具,通过封装对象的创建过程,它实现了:

  • 解耦:客户端代码与具体类实现分离

  • 扩展性:轻松添加新产品而不影响现有代码

  • 可维护性:集中管理创建逻辑

  • 灵活性:支持运行时决策和配置

在实际开发中,应当根据具体需求选择合适的工厂模式变体:

  • 对于简单场景,简单工厂足够高效

  • 对于需要高度扩展的系统,工厂方法是最佳选择

  • 避免过早优化,但为未来扩展留有余地

"设计模式不是银弹,而是工具箱中的工具。工厂模式是其中最常用且强大的工具之一。" - 设计模式实践者

相关文章:

  • wordpress 教师工作坊河南seo优化
  • 常熟做网站下载百度app免费下载安装
  • 无极领域网站郑州网络推广服务
  • 修改wordpress域名宁波seo智能优化
  • 网站 微信 app重庆seo什么意思
  • 怎样做自己的手机网站搜索引擎营销的原理是什么
  • 大模型推理-高通qnn基础
  • SpringMVC系列(三)(请求处理的十个实验(上))
  • MySQL常用函数性能优化及索引影响分析
  • PAC 学习框架:机器学习的可靠性工程
  • AI Agent模型:Plan-and-Execute、ReAct、Function Calling
  • leetcode-2138.将字符串划分为若干个长度为k的组
  • 数据库系统总结
  • 鸿蒙工具类---设置全屏效果(上下安全区背景可设置)
  • 常用的串口通信工具MobaXterm、Bus Hound、SScom等
  • GNSS位移监测站的应用场景
  • 轻巧灵动,智启未来 ——Kinova Gen3 Lite 机器人轻松解锁各行业自动化新姿势
  • 云原生灰度方案对比:服务网格灰度(Istio ) 与 K8s Ingress 灰度(Nginx Ingress )
  • TCP/UDP协议深度解析(二):TCP连接管理全解,三次握手四次挥手的完整流程
  • SoC仿真环境中自定义printf函数的实现
  • 微算法科技融合Grover算法与统一哈希函数的混合经典-量子算法技术,可在多领域高效提升文本处理效率
  • nt!CcFlushCache函数分析之nt!CcFindBcb
  • 【自己动手写AI Agent】 对于企业构建AI应用的几点思考3
  • C++(智能指针)
  • Redis—持久化
  • 设计模式 | 抽象工厂模式