.NET 设计模式—抽象工厂模式(Abstract Factory Pattern)

简介

抽象工厂模式(Abstract Factory Pattern): 抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象。客户端通过使用抽象工厂及其产品接口来创建对象,从而将客户端与具体的产品实现解耦。

优点

  • 客户端通过抽象工厂接口来创建对象,可以轻松替换不同的具体工厂,实现不同产品族的切换。
  • 抽象工厂保证了一系列相关产品的一致性,符合依赖倒置原则。

缺点

  • 增加新的产品族比较困难,需要修改抽象工厂的接口和所有具体工厂的实现。

应用场景

  • 对象的创建逻辑复杂:当对象的创建过程涉及到复杂的逻辑判断、依赖关系或者其他复杂的操作时,可以使用工厂模式将创建过程封装起来,简化客户端的代码。
  • 需要灵活地扩展产品族:如果需要在系统中添加新的产品族,而且这些产品族之间存在一定的关联关系,可以使用抽象工厂模式来管理和创建这些相关的产品。
  • 需要在运行时动态决定创建哪个具体对象:通过工厂模式,可以根据不同的条件或者配置在运行时动态地选择创建具体的对象,提供了更大的灵活性。

具体的场景

  • GUI控件库:在图形用户界面的控件库中,可以使用工厂模式来创建不同类型的控件,例如按钮、文本框、下拉框等。通过工厂方法或抽象工厂模式,可以根据需要创建不同风格或者主题的控件。
  • 数据库访问层:在数据库访问层中,可以使用工厂模式来创建不同类型的数据库连接对象,例如MySQL连接、Oracle连接等。根据配置或者运行时的参数,选择创建不同的数据库连接对象。
  • 日志记录器:在日志记录器的设计中,可以使用工厂模式来创建不同类型的日志记录器,例如文件日志、数据库日志、网络日志等。客户端可以通过工厂方法来获取适合自己需求的日志记录器对象。
  • 加密算法库:在加密算法库中,可以使用工厂模式来创建不同类型的加密算法对象,例如对称加密算法、非对称加密算法等。根据需要选择合适的加密算法对象进行数据加密和解密操作。

实现

案例:我们想通过抽象工厂模式实现一个简单的ORM,只有创建数据库连接和命令的功能,要做到在不同的数据库间切换而不需要修改代码。上层应用中,不管是使用哪种数据库,只需要更改工厂实例即可,要考虑代码的灵活性和可维护性。

  • 抽象工厂接口:
cs 复制代码
/// <summary>
/// 抽象工厂接口
/// </summary>
public interface IDbFactory
{
    IDbConnection CreateConnection();

    IDbCommand CreateCommand();
}
  • 实现SqlServer的工厂类:
cs 复制代码
/// <summary>
/// 针对 SQL Server 的工厂类
/// </summary>
public class SqlServerDbFactory : IDbFactory
{
    public IDbCommand CreateCommand()
    {
        return new SqlCommand();
    }

    public IDbConnection CreateConnection()
    {
        return new SqlConnection();
    }
}
  • 实现MySql的工厂类:
cs 复制代码
 /// <summary>
 /// 针对 MySQL 的工厂类
 /// </summary>
 public class MySqlDbFactory : IDbFactory
 {
     public IDbCommand CreateCommand()
     {
         return new MySqlCommand();
     }

     public IDbConnection CreateConnection()
     {
         return new MySqlConnection();
     }
 }
  • 使用抽象工厂创建数据库连接和命令:
cs 复制代码
/// <summary>
/// 使用抽象工厂创建数据库连接和命令
/// </summary>
public class DataAccess
{
    private readonly IDbFactory _dbFactory;

    public DataAccess(IDbFactory dbFactory)
    {
        _dbFactory = dbFactory;
    }

    public void ExecuteCommand()
    {
        using (var connection = _dbFactory.CreateConnection())
        {
            connection.ConnectionString = "Your Connection String";
            using (var command = _dbFactory.CreateCommand())
            {
                command.Connection = connection;
                command.CommandText = "Your SQL Command";
                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }
}
  • 上层应用调用:
cs 复制代码
{
    // 假设我们要使用 SQL Server
    IDbFactory dbFactory = new SqlServerDbFactory();
    DataAccess dataAccess = new DataAccess(dbFactory);
    dataAccess.ExecuteCommand();
}

{
    // 假设我们要使用 MySql
    IDbFactory dbFactory = new MySqlDbFactory();
    DataAccess dataAccess = new DataAccess(dbFactory);
    dataAccess.ExecuteCommand();
}

总结

总体而言,简单工厂模式适用于只有一个工厂类负责创建所有产品的场景;工厂方法模式适用于每个产品对应一个具体工厂的场景;抽象工厂模式适用于需要创建一系列相关产品的场景。根据具体的需求和系统设计的复杂度,选择适合的工厂模式可以提高代码的灵活性和可维护性。

相关推荐
鱟鲥鳚4 分钟前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
-银雾鸢尾-13 分钟前
C#中的StringBuilder相关方法
开发语言·c#
大模型码小白1 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司2 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地3 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
心平气和量大福大4 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
白露与泡影5 小时前
Arthas 实战指南:从方法耗时定位到 JVM 变量热修改
服务器·jvm·c#
莫逸风6 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
z123456789866 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin5211237 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python