当前位置: 首页 > 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.dtcms.com/a/338300.html

相关文章:

  • 循序渐进学 Spring (下):从注解、AOP到底层原理与整合实战
  • SpringBoot 自研运行时 SQL 调用树,3 分钟定位慢 SQL!
  • SpringBoot3整合OpenAPI3(Swagger3)完整指南
  • 王树森深度强化学习DRL(三)围棋AlphaGo+蒙特卡洛
  • Laravel中如何使用php-casbin
  • MP4 文件格式验证工具
  • onRequestHide at ORIGIN_CLIENT reason HIDE_SOFT_INPUT fromUser false
  • kafka的pull的依据
  • python 数据拟合(线性拟合、多项式回归)
  • 【2025CVPR-目标检测方向】学习稳健且硬件自适应的对象检测器,以应对边缘设备的延迟攻击
  • 【K8s】K8s 服务优雅下线调试记录
  • C# NX二次开发:字符串控件StringBlock讲解
  • 【MongoDB】常见八股合集,mongodb的特性,索引使用,优化,事务,ACID,聚合查询,数据复制机制,理解其基于raft的选举机制
  • 虚拟货币(BTC)走势分析指标体系
  • JMeter与大模型融合应用之构建AI智能体:评审性能测试脚本
  • 浅入浅出常见敏感数据处理的加密算法
  • 如何在 Ubuntu 24.04 或 22.04 LTS 上安装 PowerShell
  • SHA-256 详解
  • UE5 批量编译蓝图技巧
  • Linux Miniconda安装教程与conda常用指令介绍
  • 区块链数字存证应用
  • 健身房预约系统SSM+Mybatis实现(四、登录页面+JWT+注销)
  • 【前端智能化】AG-UI实践及原理浅析
  • 决策树的笔记
  • steal tsoding‘s pastebeam code as go server
  • 芋道审批流配置流程表单超详细介绍
  • 15.web api 6
  • Unity 中控开发 多路串口服务器(一)
  • 【Goland】:数组与切片
  • 【25-cv-09352】Maradona 品牌维权,从球衣到周边全品类侵权高危