Tutorialsteacher

关注我们

文章
  • C#
  • C# 面向对象编程
  • ASP.NET Core
  • ASP.NET MVC
  • LINQ
  • 控制反转 (IoC)
  • Web API
  • JavaScript
  • TypeScript
  • jQuery
  • Angular 11
  • Node.js
  • D3.js
  • Sass
  • Python
  • Go lang
  • HTTPS (SSL)
  • 正则表达式
  • SQL
  • SQL Server
  • PostgreSQL
  • MongoDB
  • C# - 入门
  • C# - 版本历史
  • C# - 第一个程序
  • C# - 关键词
  • C# - 类和对象
  • C# - 命名空间
  • C# - 变量
  • C# - 隐式类型变量
  • C# - 数据类型
  • 数字
  • 字符串
  • DateTime
  • 结构体
  • 枚举
  • StringBuilder
  • 匿名类型
  • 动态类型
  • 可空类型
  • C# - 值类型和引用类型
  • C# - 接口
  • C# - 运算符
  • C# - if else 语句
  • C# - 三元运算符 ?
  • C# - Switch 语句
  • C# - For 循环
  • C# - While 循环
  • C# - Do-while 循环
  • C# - 分部类
  • C# - Static 关键字
  • C# - 数组
  • 多维数组
  • 交错数组
  • C# - 索引器
  • C# - 泛型
  • 泛型约束
  • C# - 集合
  • ArrayList
  • List
  • SortedList
  • Dictionary
  • Hashtable
  • Stack
  • Queue
  • C# - 元组
  • C# - 值元组
  • C# - 内置异常
  • 异常处理
  • throw 关键字
  • 自定义异常
  • C# - 委托
  • Func 委托
  • Action 委托
  • Predicate 委托
  • 匿名方法
  • C# - 事件
  • C# - 协变
  • C# - 扩展方法
  • C# - 流 I/O
  • C# - File 类
  • C# - FileInfo 类
  • C# - 对象初始化器
  • OOP - 概述
  • 面向对象编程
  • 抽象
  • 封装
  • 关联与组合
  • 继承
  • 多态
  • 方法重写
  • 方法隐藏
  • C# - SOLID 原则
  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则
  • 设计模式
  • 单例模式
  • 抽象工厂模式
  • 工厂方法模式
Entity Framework Extensions - 提升 EF Core 9
  批量插入
  批量删除
  批量更新
  批量合并

C# 中的抽象工厂设计模式

在本文中,您将学习抽象工厂设计模式、其组件以及 C# 中的一个真实示例,以了解如何在实际场景中使用它。

抽象工厂定义

抽象工厂设计模式是一种创建型模式,它提供一个接口来创建相关或依赖对象的家族,而无需指定它们的具体类。它允许客户端代码创建属于同一家族的不同类型的对象。

这里,相关或依赖对象是指旨在一起使用以实现共同目标的一组对象。它强调某些对象应作为一个内聚组一起创建。抽象工厂提供一个抽象类或接口来创建这些对象,而具体工厂实现此抽象类或接口以生成特定家族的相关或依赖对象。

抽象工厂组件

以下是抽象工厂设计模式的组件

  1. 抽象工厂:这可以是声明用于创建相关抽象产品对象的方法的抽象类或接口。
  1. 具体工厂:这些是实现抽象工厂接口或抽象类并提供用于创建抽象产品对象的实现的类。
  1. 抽象产品:这些是定义抽象工厂可以创建的相关或依赖产品的共同行为的抽象类或接口。
  1. 具体产品:这些是实现抽象产品接口或抽象类并提供抽象产品实现的类。具体工厂将创建并返回这些类的对象。
  1. 客户端:这是一个使用抽象工厂创建产品对象的类。它不使用“new”关键字创建具体产品的对象,而是使用抽象工厂对象来获取具体产品的对象。

下图显示了抽象工厂组件及其之间的关系。

Abstract Factory Design Pattern

让我们开始创建抽象产品接口和具体产品类。请记住,具体产品应该是相关或依赖类,以实现共同功能。

示例:抽象产品
// Abstract Product A
interface IAbstractProductA
{
	void ExecuteProductA();
}

// Concrete Product A 1
class ConcreteProductA1 : IAbstractProductA
{
	public void ExecuteProductA()
	{
		Console.WriteLine("Executing ConcreteProductA1");
	}
}

// Concrete Product A 2
class ConcreteProductA2 : IAbstractProductA
{
	public void ExecuteProductA()
	{
		Console.WriteLine("Executing ConcreteProductA2");
	}
}

// Abstract Product B
interface IAbstractProductB
{
	void ExecuteProductB(IAbstractProductA prodA);
}

// Concrete Product B 1
class ConcreteProductB1 : IAbstractProductB
{
	public void ExecuteProductB(IAbstractProductA prodA)
	{
		Console.WriteLine("Inside ConcreteProductB1");
		prodA.ExecuteProductA();
	}
}

// Concrete Product B 2
class ConcreteProductB2 : IAbstractProductB
{
	public void ExecuteProductB(IAbstractProductA prodA)
	{
		Console.WriteLine("Inside ConcreteProductB2");
        prodA.ExecuteProductA();
	}
}

在上面的代码中,抽象产品 IAbstractProductA 和 IAbstractProductB 是定义具体产品必须实现的方法的接口。请注意,IAbstractProductB 包含一个与 IAbstractProductA 通信的方法,仅用于展示它们是依赖或相关产品。

具体产品 ConcreteProductA1、ConcreteProductA2、ConcreteProductB1 和 ConcreteProductB2 分别实现相应的抽象产品接口。它们提供接口中定义的操作的具体实现。

因此,这些是我们的相关产品实现,用于实现某些功能。现在,让我们创建一个抽象工厂和具体工厂,它们创建并返回上述具体产品的对象,如下所示。

示例:抽象工厂
// Abstract Factory
interface IAbstractFactory
{
	IAbstractProductA CreateProductA();
	IAbstractProductB CreateProductB();
}

// Concrete Factory 1
class ConcreteFactory1 : IAbstractFactory
{
	public IAbstractProductA CreateProductA()
	{
		return new ConcreteProductA1();
	}

	public IAbstractProductB CreateProductB()
	{
		return new ConcreteProductB1();
	}
}

// Concrete Factory 2
class ConcreteFactory2 : IAbstractFactory
{
	public IAbstractProductA CreateProductA()
	{
		return new ConcreteProductA2();
	}

	public IAbstractProductB CreateProductB()
	{
		return new ConcreteProductB2();
	}
}

在上面的代码中,IAbstractFactory 接口表示一个抽象工厂,它定义了 CreateProductA() 和 CreateProductB() 方法,分别用于创建 IAbstractProductA 和 IAbstractProductB 的实例。请注意,您可以根据您的要求使用抽象类而不是接口。

具体工厂 ConcreteFactory1 和 ConcreteFactory2 实现 IAbstractFactory 接口并重写方法以创建两个具体产品。

现在,让我们看看客户端类如何使用这个抽象工厂来获取具体产品的对象。

示例:抽象工厂的使用
// Client
class Client
{
	private IAbstractProductA _productA;
	private IAbstractProductB _productB;
	public Client(IAbstractFactory factory)
	{
		_productA = factory.CreateProductA();
		_productB = factory.CreateProductB();
	}

	public void Execute()
	{
		_productA.ExecuteProductA();
		_productB.ExecuteProductB(_productA);
	}
}

Client 类在其构造函数中接收抽象工厂的实例。然后它使用工厂创建抽象产品(IAbstractProductA 和 IAbstractProductB)的实例。客户端可以在创建的产品上执行操作。

示例:抽象工厂程序
public class Program
{
	public static void Main(string[] args)
	{
		Console.WriteLine("Using factory1");
		IAbstractFactory factory1 = new ConcreteFactory1();
		Client client1 = new Client(factory1);
		client1.Execute();
		
		Console.WriteLine("Using factory2");
		IAbstractFactory factory2 = new ConcreteFactory2();
		Client client2 = new Client(factory2);
		client2.Execute();	
    }
}
尝试一下

Main 方法通过创建不同工厂(ConcreteFactory1 和 ConcreteFactory2)的实例并将它们传递给 Client 构造函数来演示抽象工厂模式的使用。然后客户端使用这些工厂来创建和执行产品。

现在,让我们根据抽象工厂模式创建一个新的 DBConnectionFactory 示例。

真实世界的例子

让我们考虑一个真实的例子,您的应用程序中访问多个数据库。假设您需要连接到 SQL Server 和 PostgreSQL 数据库以在您的应用程序中保存或检索一些数据。在这种情况下,我们可以使用抽象工厂设计模式来创建数据库工厂和其他组件。

抽象工厂真实世界示例
using System;

//Abstract Product
interface IDBConnection
{
	void Connect();
}

//Concrete Product
class SQLServerDBConnection : IDBConnection
{
	public void Connect()
	{
		Console.WriteLine("Connected to SQL Server database...");
	}
}

//Concrete Product
class PostgreDBConnection : IDBConnection
{
	public void Connect()
	{
		Console.WriteLine("Connected to PostGre database.");
	}
}

//Abstract Product
interface IDBCommand
{
	void Execute(string query, IDBConnection con);
}

//Concrete Product
class SQLServerDBCommand : IDBCommand
{
	public void Execute(string query, IDBConnection con)
	{
		con.Connect();
		Console.WriteLine("Executing SQL Server query: " + query);
	}
}

//Concrete Product
class PostgreDBCommand : IDBCommand
{
	public void Execute(string query, IDBConnection con)
	{
		con.Connect();
		Console.WriteLine("Executing PostGreSQL Server query: " + query);
	}
}

//Abstract Factory
interface IDBFactory
{
	IDBConnection CreateConnection();
	IDBCommand CreateCommand();
}

//Concrete Factory for SQL Server
class SQLServerFactory : IDBFactory
{
	public IDBConnection CreateConnection()
	{
		return new SQLServerDBConnection();
	}

	public IDBCommand CreateCommand()
	{
		return new SQLServerDBCommand();
	}
}

// Concrete Factory for PostgreSQL
class PostGreSQLFactory : IDBFactory
{
	public IDBConnection CreateConnection()
	{
		return new PostgreDBConnection();
	}

	public IDBCommand CreateCommand()
	{
		return new PostgreDBCommand();
	}
}

//Client
class DBQueryClient
{
	private IDBConnection _connection;
	private IDBCommand _command;

	public DBQueryClient(IDBFactory factory)
	{
		_connection = factory.CreateConnection();
		_command = factory.CreateCommand();
	}

	public void ExecuteQuery(string query)
	{		
		_command.Execute(query, _connection);
	}
}

public class Program
{
	public static void Main()
	{
		Console.WriteLine("Using SQL Server Factory");
		IDBFactory sqlServerFactory = new SQLServerFactory();
		DBQueryClient sqlServerClient = new DBQueryClient(sqlServerFactory);
		sqlServerClient.ExecuteQuery("SELECT * FROM Customers");

		Console.WriteLine("
Using PostGre Factory");
		IDBFactory postgreFactory = new PostGreSQLFactory();
		DBQueryClient postgreClient = new DBQueryClient(postgreFactory);
		postgreClient.ExecuteQuery("SELECT * FROM Customers");
	}
}
尝试一下
输出
Using SQL Server Factory Connected to SQL Server database... Executing SQL Server query: SELECT * FROM Customers Using PostGre Factory Connected to PostGre database. Executing PostGreSQL Server query: SELECT * FROM Customers

在上面的示例中,我们定义了两个抽象产品接口:IDBConnection 和 IDBCommand。IDBConnection 定义了连接数据库的方法,IDBCommand 定义了执行数据库查询的方法。这些是依赖的抽象产品,因为 IDBCommand 需要一个 IDBConnection 对象来执行查询。

接下来,SQLServerDBConnection 和 PostgreDBConnection 是实现 IDBConnection 接口的具体产品类。这两个类都实现了 Connect 方法以建立与相应数据库的连接。

同样,SQLServerDBCommand 和 PostgreDBCommand 是实现 IDBCommand 接口的具体产品类。这些类实现了 Execute 方法以在各自的数据库上执行查询。

一个名为 IDBFactory 的抽象工厂接口。此接口定义了负责创建 IDBConnection 和 IDBCommand 实例的工厂方法。

SQLServerFactory 和 PostGreSQLFactory 是实现 CreateConnection 和 CreateCommand 方法以创建相应具体产品类实例的具体工厂。

现在,DBQueryClient 是客户端类,它根据传入的工厂类查询数据库。此类在其构造函数中接受抽象工厂的实例,并使用它创建具体产品实例。然后,DBQueryClient 利用创建的 IDBConnection 和 IDBCommand 对象在数据库上执行查询。

最后,在 Main 方法中,代码演示了抽象工厂和创建对象的使用。它使用 SQLServerFactory 创建客户端,使用创建的对象执行查询,然后使用 PostGreSQLFactory 重复该过程。

通过此实现,抽象工厂模式提供了一个接口,用于创建相关对象家族,而无需指定它们的具体类,从而允许客户端可互换地使用任何可用家族。

因此,抽象工厂设计模式提供了一种在不指定具体类的情况下创建相关或依赖对象家族的方法。它促进了松散耦合,并允许在创建对象时轻松扩展和灵活。通过使用抽象工厂模式,您可以轻松地在应用程序中切换不同的对象家族,而不会影响客户端代码。

TUTORIALSTEACHER.COM

TutorialsTeacher.com 是您权威的技术教程来源,旨在通过循序渐进的方法,指导您掌握各种网络和其他技术。

我们的内容帮助所有级别的学习者轻松快速地学习技术。通过访问此平台,您承认您已审查并同意遵守我们的使用条款和隐私政策,这些条款和政策旨在保护您的体验和隐私权。

[email protected]

关于我们使用条款隐私政策
copywrite-symbol

2024 TutorialsTeacher.com. (v 1.2) 版权所有。