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

94、23种设计模式之工厂方法模式

工厂方法模式(Factory Method Pattern)是23种经典设计模式中的创建型模式,其核心思想是将对象的实例化延迟到子类中完成,通过定义一个创建对象的接口(工厂方法),让子类决定具体实例化哪个类。以下是其关键要点与实现分析:

一、模式结构

工厂方法模式包含四个核心角色:

1.抽象产品(Product)

  • 定义产品的公共接口,所有具体产品必须实现该接口。

  • 示例:ILog接口定义日志记录的通用方法(如Write)。

2.具体产品(Concrete Product)

  • 实现抽象产品接口,提供具体功能。
  • 示例:FileLog(文件日志)和DatabaseLog(数据库日志)实现ILog接口。

3.抽象工厂(Creator)

  • 声明工厂方法(如CreateProduct),返回抽象产品类型。
  • 可包含默认实现或通用逻辑。
  • 示例:LogFactory抽象类定义CreateLog方法。

4.具体工厂(Concrete Creator)

  • 实现抽象工厂的工厂方法,返回具体产品实例。
  • 示例:FileLogFactory和DatabaseLogFactory分别创建FileLog和DatabaseLog。

二、C# 实现示例

以下是一个完整的C#代码示例,展示日志系统的工厂方法模式实现:

using System;// 抽象产品:日志接口
public interface ILog
{void Write(string message);
}// 具体产品:文件日志
public class FileLog : ILog
{public void Write(string message){Console.WriteLine($"[文件日志] {message}");}
}// 具体产品:数据库日志
public class DatabaseLog : ILog
{public void Write(string message){Console.WriteLine($"[数据库日志] {message}");}
}// 抽象工厂:日志工厂
public abstract class LogFactory
{public abstract ILog CreateLog();// 通用日志方法(可选)public void LogMessage(string message){ILog log = CreateLog();log.Write(message);}
}// 具体工厂:文件日志工厂
public class FileLogFactory : LogFactory
{public override ILog CreateLog(){return new FileLog();}
}// 具体工厂:数据库日志工厂
public class DatabaseLogFactory : LogFactory
{public override ILog CreateLog(){return new DatabaseLog();}
}// 客户端代码
class Program
{static void Main(string[] args){// 使用文件日志工厂LogFactory fileFactory = new FileLogFactory();fileFactory.LogMessage("这是一条文件日志");// 使用数据库日志工厂LogFactory dbFactory = new DatabaseLogFactory();dbFactory.LogMessage("这是一条数据库日志");}
}

输出结果:

[文件日志] 这是一条文件日志
[数据库日志] 这是一条数据库日志

三、模式优势

1.解耦客户端与具体产品

  • 客户端通过抽象工厂和抽象产品接口交互,无需关心具体实现类。

2.符合开闭原则(OCP)

  • 新增产品类型时,只需添加具体产品和工厂类,无需修改现有代码。
  • 示例:新增ConsoleLog时,仅需创建ConsoleLog类和ConsoleLogFactory类。

3.单一职责原则(SRP)

  • 工厂类负责对象创建,客户端代码专注于业务逻辑。

4.灵活性与可扩展性

  • 支持动态切换产品类型(如通过配置文件选择工厂)。

四、适用场景

1.需要动态决定创建哪种产品

  • 例如:根据用户输入或配置文件选择日志类型(文件/数据库/控制台)。

2.希望解耦对象创建与使用

  • 客户端只需知道抽象接口,无需依赖具体实现。

3.系统需要支持多种产品类型

  • 例如:不同数据库连接(MySQL、Oracle)、不同UI组件(Windows按钮、macOS按钮)。

五、工厂方法模式和抽象工厂模式对比

1. 核心目标

工厂方法模式
  • 单一产品创建:通过子类决定实例化哪一个具体产品(一个产品对应一个工厂)。

  • 动态扩展:新增产品时,只需新增具体工厂类(符合开闭原则)。

  • 典型场景:日志系统(文件日志/数据库日志)、资源加载(如Unity的Resources.Load)。

抽象工厂模式
  • 产品族创建:创建一组相关或依赖的产品(如一套UI组件、一套数据库连接)。
  • 统一风格:确保客户端获取的产品属于同一系列(如Windows风格按钮+文本框)。
  • 典型场景:跨平台UI库(Windows/macOS控件)、数据库访问层(MySQL/Oracle连接池)。

2. 结构复杂度

工厂方法
  • 简单直接,每个工厂负责一个产品。
抽象工厂
  • 复杂度高,需维护产品族的一致性(如新增“Linux按钮”需同时修改所有具体工厂)。

3. 如何选择?

用工厂方法模式
  • 需要灵活创建单一类型对象,且产品类型可能动态变化。
  • 示例:根据配置文件选择日志方式(文件/数据库)。
用抽象工厂模式
  • 需要创建一组相关对象,并确保它们属于同一风格或系列。
  • 示例:开发跨平台应用时,统一生成Windows/macOS风格的UI组件。
总结
  • 工厂方法模式是“一对一”创建,抽象工厂模式是“一对多”创建,前者更灵活,后者更强调产品族的一致性。

六、实际应用案例

1.ASP.NET Core 日志系统

  • 通过ILoggerFactory动态注册日志提供程序(如控制台、文件、Azure)。

2.Unity 游戏引擎

  • 资源加载(如Resources.Load)可视为工厂方法的变体,根据路径动态创建游戏对象。

3.数据库连接池

  • 不同数据库(MySQL、SQL Server)对应不同的连接工厂,通过工厂方法创建连接对象。

七、总结

工厂方法模式通过将对象创建委托给子类,实现了解耦、可扩展性和符合开闭原则,适合需要灵活创建对象的场景。若产品类型较少且固定,可考虑简单工厂模式以降低复杂度;若需严格遵循OCP或产品类型动态变化,工厂方法模式是更优选择。

在这里插入图片描述

http://www.lryc.cn/news/624806.html

相关文章:

  • Redis--day8--黑马点评--分布式锁(一)
  • 单片机驱动LCD显示模块LM6029BCW
  • 机器学习-决策树:从原理到实战的机器学习入门指南
  • LLM - windows下的Dify离线部署:从镜像打包到无网环境部署(亲测)
  • VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
  • 【Python 小工具】一键把源表 INSERT SQL 转换成目标表 INSERT SQL
  • 华为认证 HCIA/HCIP/HCIE 全面解析(2025 版)
  • Next.js 性能优化:打造更快的应用
  • docker——docker执行roslaunch显示错误
  • Harmonyos之字体设置功能
  • Java任务执行队列的优化
  • 王树森深度强化学习DRL(三)围棋AlphaGo+蒙特卡洛
  • 《Python学习之第三方库:开启无限可能》
  • 【网络安全实验报告】实验六: 病毒防护实验
  • 【加密PMF】psk-pmk-ptk
  • 使用WinDbg对软件崩溃信息进行抓包的方法
  • AI 在金融领域的落地案例
  • 为Vue TypeScript 项目添加 router 路由,跳转到Chat AI页面
  • 2025 年无毒冷却液市场深度全景调研及投资前景分析
  • Qwen Code宣布每天免费调用2000次,且无Token限制
  • 物联网智能边缘架构:流数据处理与设备管理的协同优化
  • Linux常用命令详解
  • 增强服务器防御能力的自动化工具 Fail2Ban
  • MySQL实战优化高手教程 – 从架构原理到生产调优
  • iOS 正式包签名指南
  • 【C#补全计划】预处理器指令
  • 【MongoDB】常见八股合集,mongodb的特性,索引使用,优化,事务,ACID,聚合查询,数据复制机制,理解其基于raft的选举机制
  • 【Langchain系列五】DbGPT——Langchain+PG构建结构化数据库智能问答系统
  • MongoDB新手教学
  • Flutter 多功能列表项:图标、文字与Switch组合