C# 中的 简单工厂模式 (Simple Factory)

简单工厂模式 (Simple Factory)

简单工厂模式虽然不属于GoF 23种设计模式,但它是最常用、最基础的设计模式之一,特别适合初学者理解工厂概念。

简单工厂模式详解

目的:定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例通常具有共同的父类。

优点

  • 客户端与具体产品类解耦
  • 将对象的创建集中管理,便于维护
  • 不需要记住具体类名,只需要知道参数

缺点

  • 工厂类职责过重,增加新产品需要修改工厂类
  • 不符合开闭原则
csharp 复制代码
using System;

// 产品接口
public interface IProduct
{
    string Operation(); // 产品操作
}

// 具体产品A
public class ConcreteProductA : IProduct
{
    public string Operation()
    {
        return "Result of ConcreteProductA"; // 产品A的具体操作
    }
}

// 具体产品B
public class ConcreteProductB : IProduct
{
    public string Operation()
    {
        return "Result of ConcreteProductB"; // 产品B的具体操作
    }
}

// 具体产品C
public class ConcreteProductC : IProduct
{
    public string Operation()
    {
        return "Result of ConcreteProductC"; // 产品C的具体操作
    }
}

// 简单工厂类
public class SimpleFactory
{
    // 根据类型参数创建不同的产品
    public IProduct CreateProduct(string type)
    {
        switch (type.ToUpper())
        {
            case "A":
                Console.WriteLine("Factory: Creating Product A");
                return new ConcreteProductA(); // 创建产品A
            case "B":
                Console.WriteLine("Factory: Creating Product B");
                return new ConcreteProductB(); // 创建产品B
            case "C":
                Console.WriteLine("Factory: Creating Product C");
                return new ConcreteProductC(); // 创建产品C
            default:
                throw new ArgumentException($"Invalid product type: {type}"); // 无效类型异常
        }
    }
    
    // 使用枚举的版本,更安全
    public IProduct CreateProduct(ProductType type)
    {
        switch (type)
        {
            case ProductType.A:
                Console.WriteLine("Factory: Creating Product A");
                return new ConcreteProductA(); // 创建产品A
            case ProductType.B:
                Console.WriteLine("Factory: Creating Product B");
                return new ConcreteProductB(); // 创建产品B
            case ProductType.C:
                Console.WriteLine("Factory: Creating Product C");
                return new ConcreteProductC(); // 创建产品C
            default:
                throw new ArgumentException($"Invalid product type: {type}"); // 无效类型异常
        }
    }
}

// 产品类型枚举
public enum ProductType
{
    A,
    B,
    C
}

// 客户端代码
class Program
{
    static void Main()
    {
        // 创建工厂实例
        var factory = new SimpleFactory();
        
        Console.WriteLine("=== 使用字符串参数版本 ===");
        // 客户端不需要知道具体产品类,只需要知道类型标识
        IProduct productA = factory.CreateProduct("A");
        Console.WriteLine($"Client: {productA.Operation()}"); // 输出产品A的操作结果
        
        IProduct productB = factory.CreateProduct("B");
        Console.WriteLine($"Client: {productB.Operation()}"); // 输出产品B的操作结果
        
        IProduct productC = factory.CreateProduct("C");
        Console.WriteLine($"Client: {productC.Operation()}"); // 输出产品C的操作结果
        
        Console.WriteLine("\n=== 使用枚举参数版本(推荐) ===");
        // 使用枚举更安全,避免拼写错误
        IProduct productA2 = factory.CreateProduct(ProductType.A);
        Console.WriteLine($"Client: {productA2.Operation()}"); // 输出产品A的操作结果
        
        IProduct productB2 = factory.CreateProduct(ProductType.B);
        Console.WriteLine($"Client: {productB2.Operation()}"); // 输出产品B的操作结果
        
        Console.WriteLine("\n=== 演示异常处理 ===");
        try
        {
            // 尝试创建不存在的产品类型
            IProduct invalidProduct = factory.CreateProduct("X");
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine($"Error: {ex.Message}"); // 输出错误信息
        }
    }
}

/* 输出结果:
=== 使用字符串参数版本 ===
Factory: Creating Product A
Client: Result of ConcreteProductA
Factory: Creating Product B
Client: Result of ConcreteProductB
Factory: Creating Product C
Client: Result of ConcreteProductC

=== 使用枚举参数版本(推荐) ===
Factory: Creating Product A
Client: Result of ConcreteProductA
Factory: Creating Product B
Client: Result of ConcreteProductB

=== 演示异常处理 ===
Error: Invalid product type: X
*/

实际应用场景示例:数据库连接工厂

csharp 复制代码
using System;

// 数据库连接接口
public interface IDatabaseConnection
{
    void Connect();      // 连接数据库
    void Disconnect();   // 断开连接
    string Query(string sql); // 执行查询
}

// SQL Server 连接
public class SqlServerConnection : IDatabaseConnection
{
    public void Connect()
    {
        Console.WriteLine("Connected to SQL Server Database"); // 连接SQL Server
    }
    
    public void Disconnect()
    {
        Console.WriteLine("Disconnected from SQL Server Database"); // 断开SQL Server连接
    }
    
    public string Query(string sql)
    {
        return $"SQL Server executed: {sql}"; // SQL Server执行查询
    }
}

// MySQL 连接
public class MySqlConnection : IDatabaseConnection
{
    public void Connect()
    {
        Console.WriteLine("Connected to MySQL Database"); // 连接MySQL
    }
    
    public void Disconnect()
    {
        Console.WriteLine("Disconnected from MySQL Database"); // 断开MySQL连接
    }
    
    public string Query(string sql)
    {
        return $"MySQL executed: {sql}"; // MySQL执行查询
    }
}

// Oracle 连接
public class OracleConnection : IDatabaseConnection
{
    public void Connect()
    {
        Console.WriteLine("Connected to Oracle Database"); // 连接Oracle
    }
    
    public void Disconnect()
    {
        Console.WriteLine("Disconnected from Oracle Database"); // 断开Oracle连接
    }
    
    public string Query(string sql)
    {
        return $"Oracle executed: {sql}"; // Oracle执行查询
    }
}

// 数据库类型枚举
public enum DatabaseType
{
    SqlServer,
    MySql,
    Oracle
}

// 数据库连接工厂
public class DatabaseConnectionFactory
{
    // 创建数据库连接
    public IDatabaseConnection CreateConnection(DatabaseType dbType)
    {
        switch (dbType)
        {
            case DatabaseType.SqlServer:
                Console.WriteLine("Creating SQL Server connection..."); // 创建SQL Server连接
                return new SqlServerConnection();
            case DatabaseType.MySql:
                Console.WriteLine("Creating MySQL connection..."); // 创建MySQL连接
                return new MySqlConnection();
            case DatabaseType.Oracle:
                Console.WriteLine("Creating Oracle connection..."); // 创建Oracle连接
                return new OracleConnection();
            default:
                throw new ArgumentException($"Unsupported database type: {dbType}"); // 不支持的数据库类型
        }
    }
    
    // 从配置字符串创建连接(更灵活的方式)
    public IDatabaseConnection CreateConnection(string connectionString)
    {
        if (connectionString.ToLower().Contains("server=sql"))
        {
            Console.WriteLine("Detected SQL Server from connection string"); // 从连接字符串检测到SQL Server
            return new SqlServerConnection();
        }
        else if (connectionString.ToLower().Contains("server=mysql"))
        {
            Console.WriteLine("Detected MySQL from connection string"); // 从连接字符串检测到MySQL
            return new MySqlConnection();
        }
        else if (connectionString.ToLower().Contains("server=oracle"))
        {
            Console.WriteLine("Detected Oracle from connection string"); // 从连接字符串检测到Oracle
            return new OracleConnection();
        }
        else
        {
            throw new ArgumentException("Unable to determine database type from connection string"); // 无法从连接字符串确定数据库类型
        }
    }
}

// 客户端代码
class Program
{
    static void Main()
    {
        // 创建数据库连接工厂
        var dbFactory = new DatabaseConnectionFactory();
        
        Console.WriteLine("=== 数据库连接工厂演示 ===\n");
        
        // 创建SQL Server连接
        Console.WriteLine("1. 创建SQL Server连接:");
        IDatabaseConnection sqlConn = dbFactory.CreateConnection(DatabaseType.SqlServer);
        sqlConn.Connect(); // 连接数据库
        Console.WriteLine(sqlConn.Query("SELECT * FROM Users")); // 执行查询
        sqlConn.Disconnect(); // 断开连接
        
        Console.WriteLine();
        
        // 创建MySQL连接
        Console.WriteLine("2. 创建MySQL连接:");
        IDatabaseConnection mysqlConn = dbFactory.CreateConnection(DatabaseType.MySql);
        mysqlConn.Connect(); // 连接数据库
        Console.WriteLine(mysqlConn.Query("SELECT * FROM Products")); // 执行查询
        mysqlConn.Disconnect(); // 断开连接
        
        Console.WriteLine();
        
        // 通过连接字符串创建连接
        Console.WriteLine("3. 通过连接字符串创建Oracle连接:");
        IDatabaseConnection oracleConn = dbFactory.CreateConnection("Server=oracle;Database=test;Uid=user;Pwd=pass;");
        oracleConn.Connect(); // 连接数据库
        Console.WriteLine(oracleConn.Query("SELECT * FROM Orders")); // 执行查询
        oracleConn.Disconnect(); // 断开连接
        
        Console.WriteLine("\n=== 工厂模式优势总结 ===");
        Console.WriteLine("✓ 客户端与具体数据库类解耦");
        Console.WriteLine("✓ 新增数据库类型只需修改工厂类");
        Console.WriteLine("✓ 统一的创建接口,便于管理");
    }
}

/* 输出结果:
=== 数据库连接工厂演示 ===

1. 创建SQL Server连接:
Creating SQL Server connection...
Connected to SQL Server Database
SQL Server executed: SELECT * FROM Users
Disconnected from SQL Server Database

2. 创建MySQL连接:
Creating MySQL connection...
Connected to MySQL Database
MySQL executed: SELECT * FROM Products
Disconnected from MySQL Database

3. 通过连接字符串创建Oracle连接:
Detected Oracle from connection string
Connected to Oracle Database
Oracle executed: SELECT * FROM Orders
Disconnected from Oracle Database

=== 工厂模式优势总结 ===
✓ 客户端与具体数据库类解耦
✓ 新增数据库类型只需修改工厂类
✓ 统一的创建接口,便于管理
*/

静态简单工厂

csharp 复制代码
using System;

// 静态简单工厂 - 不需要实例化工厂类
public static class StaticSimpleFactory
{
    // 静态方法创建产品
    public static IProduct CreateProduct(string type)
    {
        switch (type.ToUpper())
        {
            case "A":
                Console.WriteLine("Static Factory: Creating Product A");
                return new ConcreteProductA(); // 创建产品A
            case "B":
                Console.WriteLine("Static Factory: Creating Product B");
                return new ConcreteProductB(); // 创建产品B
            case "C":
                Console.WriteLine("Static Factory: Creating Product C");
                return new ConcreteProductC(); // 创建产品C
            default:
                throw new ArgumentException($"Invalid product type: {type}"); // 无效类型异常
        }
    }
    
    // 泛型版本,更灵活
    public static T CreateProduct<T>() where T : IProduct, new()
    {
        Console.WriteLine($"Static Factory: Creating {typeof(T).Name}");
        return new T(); // 创建泛型指定的产品
    }
}

// 使用静态工厂的客户端代码
class StaticFactoryClient
{
    static void Main()
    {
        Console.WriteLine("=== 静态简单工厂演示 ===\n");
        
        // 使用字符串参数
        IProduct productA = StaticSimpleFactory.CreateProduct("A");
        Console.WriteLine($"Client: {productA.Operation()}"); // 输出产品A的操作结果
        
        // 使用泛型版本
        IProduct productB = StaticSimpleFactory.CreateProduct<ConcreteProductB>();
        Console.WriteLine($"Client: {productB.Operation()}"); // 输出产品B的操作结果
        
        Console.WriteLine("\n=== 静态工厂优势 ===");
        Console.WriteLine("✓ 无需创建工厂实例");
        Console.WriteLine("✓ 调用更简洁");
        Console.WriteLine("✓ 适合简单的创建逻辑");
    }
}

/* 输出结果:
=== 静态简单工厂演示 ===

Static Factory: Creating Product A
Client: Result of ConcreteProductA
Static Factory: Creating ConcreteProductB
Client: Result of ConcreteProductB

=== 静态工厂优势 ===
✓ 无需创建工厂实例
✓ 调用更简洁
✓ 适合简单的创建逻辑
*/

简单工厂 vs 工厂方法 vs 抽象工厂

模式 特点 适用场景
简单工厂 一个工厂类,根据参数创建不同产品 产品类型不多,创建逻辑简单
工厂方法 每个产品对应一个工厂类 产品类型多,需要扩展性好
抽象工厂 创建产品家族,确保兼容性 需要创建相关产品组

总结

简单工厂模式是最容易理解和使用的创建型模式,它的核心思想是:

  1. 封装变化:将对象的创建过程封装起来
  2. 解耦:客户端不需要知道具体产品的类名
  3. 集中管理:所有创建逻辑在一个地方维护

使用时机

  • 当需要创建的对象类型不多时
  • 客户端不关心对象的创建细节时
  • 需要统一管理对象创建时

注意事项

  • 当产品类型很多时,工厂类会变得臃肿
  • 新增产品需要修改工厂类,违反开闭原则
  • 考虑使用工厂方法模式来避免这些问题

简单工厂是理解更复杂工厂模式的基础,在实际项目中非常实用!

相关推荐
ajassi20003 小时前
开源 C# 快速开发(十一)线程
http·开源·c#
周杰伦fans11 小时前
C# 23种设计模式详解与示例
开发语言·设计模式·c#
xb113213 小时前
C#——方法的定义、调用与调试
开发语言·c#
code bean13 小时前
【C#】以 BlockingCollection 为核心的多相机 YOLO 检测任务处理框架
c#
时光追逐者15 小时前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf
-可乐加冰吗17 小时前
SuperMap iObjects .NET 11i 二次开发(十五)—— 类型转换之面转点
visualstudio·c#·.net
ajassi200018 小时前
开源 C# 快速开发(十二)进程监控
开发语言·开源·c#
大飞pkz20 小时前
【设计模式】代理模式
开发语言·设计模式·c#·代理模式
sali-tec21 小时前
C# 基于halcon的视觉工作流-章40-OCR训练识别
开发语言·图像处理·算法·计算机视觉·c#·ocr