定义
抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式强调的是对象族的创建,而不是单一对象的创建。
用例写法
假设我们有一个场景,需要根据不同的平台(如 Windows 和 MacOS)创建不同的用户界面组件(如按钮和文本框)。
csharp
// 用户界面组件接口
public interface IButton
{
void Render();
}
public interface ITextBox
{
void Render();
}
// Windows用户界面组件
public class WindowsButton : IButton
{
public void Render() => Console.WriteLine("Rendering Windows Button...");
}
public class WindowsTextBox : ITextBox
{
public void Render() => Console.WriteLine("Rendering Windows TextBox...");
}
// MacOS用户界面组件
public class MacOSButton : IButton
{
public void Render() => Console.WriteLine("Rendering MacOS Button...");
}
public class MacOSTextBox : ITextBox
{
public void Render() => Console.WriteLine("Rendering MacOS TextBox...");
}
// 抽象工厂接口
public interface IUIComponentFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
// Windows用户界面组件工厂
public class WindowsUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
}
// MacOS用户界面组件工厂
public class MacOSUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new MacOSButton();
public ITextBox CreateTextBox() => new MacOSTextBox();
}
// 配置类
public class Configuration
{
public string OS { get; set; }
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
Configuration config = new Configuration { OS = "Windows" };
IUIComponentFactory factory;
if (config.OS == "Windows")
{
factory = new WindowsUIComponentFactory();
}
else if (config.OS == "MacOS")
{
factory = new MacOSUIComponentFactory();
}
else
{
throw new ArgumentException("Unsupported operating system");
}
IButton button = factory.CreateButton();
ITextBox textBox = factory.CreateTextBox();
button.Render();
textBox.Render();
}
}
类图:
IButton +void Render() ITextBox +void Render() WindowsButton +void Render() WindowsTextBox +void Render() MacOSButton +void Render() MacOSTextBox +void Render() IUIComponentFactory +IButton CreateButton() +ITextBox CreateTextBox() WindowsUIComponentFactory +IButton CreateButton() +ITextBox CreateTextBox() MacOSUIComponentFactory +IButton CreateButton() +ITextBox CreateTextBox() Configuration -string OS +Configuration() Program +static void Main(string[] args)
解释
- 用户界面组件接口 (
IButton
和ITextBox
):定义了渲染按钮和文本框的方法。 - 具体用户界面组件 (
WindowsButton
、WindowsTextBox
、MacOSButton
、MacOSTextBox
):实现了具体的按钮和文本框渲染逻辑。 - 抽象工厂接口 (
IUIComponentFactory
):定义了创建按钮和文本框的方法。 - 具体工厂类 (
WindowsUIComponentFactory
和MacOSUIComponentFactory
):实现了具体的按钮和文本框创建逻辑。 - 配置类 (
Configuration
):用于存储操作系统的配置信息。 - 客户端代码 (
Program
):根据配置信息选择合适的工厂类,并使用工厂类创建具体的用户界面组件,然后调用其渲染方法。
用途
- 创建一系列相关对象:当需要创建一系列相关或相互依赖的对象时,使用抽象工厂模式可以确保这些对象的一致性。
- 解耦对象的创建和使用:客户端代码只需要依赖抽象工厂接口,不需要知道具体的产品类,从而降低了耦合度。
- 支持多平台:适用于需要在不同平台上创建不同版本的对象的场景。
优点
- 易于交换产品族:可以在运行时动态地切换不同的产品族,只需更换工厂对象即可。
- 支持开闭原则:增加新的产品族时,只需要添加新的具体工厂类,不需要修改现有的代码,符合开闭原则。
- 高度模块化:每个产品族的创建逻辑都封装在对应的工厂类中,模块化程度高。
缺点
- 系统复杂度增加:引入了更多的接口和类,系统结构变得更复杂。
- 增加代码量:每增加一个新的产品族,都需要增加相应的工厂类和产品类。
- 产品族扩展困难:如果需要增加新的产品类型,必须修改所有的工厂类,这违反了开闭原则。
适用场景
- 产品族多:当系统中有多个产品族,且每个产品族中的产品需要一起使用时。
- 多平台支持:需要在不同平台上创建不同版本的对象时。
- 对象创建逻辑复杂:对象的创建逻辑较为复杂,需要集中管理和控制时。
实际开发中的应用
1. 多平台用户界面框架
假设我们正在开发一个多平台用户界面框架,需要根据不同的操作系统创建不同的用户界面组件。
csharp
// 用户界面组件接口
public interface IButton
{
void Render();
}
public interface ITextBox
{
void Render();
}
// Windows用户界面组件
public class WindowsButton : IButton
{
public void Render() => Console.WriteLine("Rendering Windows Button...");
}
public class WindowsTextBox : ITextBox
{
public void Render() => Console.WriteLine("Rendering Windows TextBox...");
}
// MacOS用户界面组件
public class MacOSButton : IButton
{
public void Render() => Console.WriteLine("Rendering MacOS Button...");
}
public class MacOSTextBox : ITextBox
{
public void Render() => Console.WriteLine("Rendering MacOS TextBox...");
}
// 抽象工厂接口
public interface IUIComponentFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
// Windows用户界面组件工厂
public class WindowsUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
}
// MacOS用户界面组件工厂
public class MacOSUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new MacOSButton();
public ITextBox CreateTextBox() => new MacOSTextBox();
}
// 配置类
public class Configuration
{
public string OS { get; set; }
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
Configuration config = new Configuration { OS = "Windows" };
IUIComponentFactory factory;
if (config.OS == "Windows")
{
factory = new WindowsUIComponentFactory();
}
else if (config.OS == "MacOS")
{
factory = new MacOSUIComponentFactory();
}
else
{
throw new ArgumentException("Unsupported operating system");
}
IButton button = factory.CreateButton();
ITextBox textBox = factory.CreateTextBox();
button.Render();
textBox.Render();
}
}
解释
- 用户界面组件接口 (
IButton
和ITextBox
):定义了渲染按钮和文本框的方法。 - 具体用户界面组件 (
WindowsButton、WindowsTextBox、MacOSButton、MacOSTextBox
):实现了具体的按钮和文本框渲染逻辑。 - 抽象工厂接口 (
IUIComponentFactory
):定义了创建按钮和文本框的方法。 - 具体工厂类 (
WindowsUIComponentFactory
和MacOSUIComponentFactory
):实现了具体的按钮和文本框创建逻辑。 - 配置类 (
Configuration
):用于存储操作系统的配置信息。 - 客户端代码 (
Program
):根据配置信息选择合适的工厂类,并使用工厂类创建具体的用户界面组件,然后调用其渲染方法。
2. 数据库操作框架
假设我们正在开发一个数据库操作框架,需要根据不同的数据库类型创建不同的数据访问对象。
csharp
// 数据访问接口
public interface IDbConnection
{
void Connect();
void Disconnect();
}
public interface IDbCommand
{
void Execute();
}
// MySQL数据库操作
public class MySqlConnection : IDbConnection
{
public void Connect() => Console.WriteLine("Connecting to MySQL database...");
public void Disconnect() => Console.WriteLine("Disconnecting from MySQL database...");
}
public class MySqlCommand : IDbCommand
{
public void Execute() => Console.WriteLine("Executing MySQL command...");
}
// SQL Server数据库操作
public class SqlServerConnection : IDbConnection
{
public void Connect() => Console.WriteLine("Connecting to SQL Server database...");
public void Disconnect() => Console.WriteLine("Disconnecting from SQL Server database...");
}
public class SqlCommand : IDbCommand
{
public void Execute() => Console.WriteLine("Executing SQL Server command...");
}
// 抽象工厂接口
public interface IDbFactory
{
IDbConnection CreateConnection();
IDbCommand CreateCommand();
}
// MySQL数据库工厂
public class MySqlDbFactory : IDbFactory
{
public IDbConnection CreateConnection() => new MySqlConnection();
public IDbCommand CreateCommand() => new MySqlCommand();
}
// SQL Server数据库工厂
public class SqlServerDbFactory : IDbFactory
{
public IDbConnection CreateConnection() => new SqlServerConnection();
public IDbCommand CreateCommand() => new SqlCommand();
}
// 配置类
public class Configuration
{
public string DatabaseType { get; set; }
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
Configuration config = new Configuration { DatabaseType = "MySQL" };
IDbFactory factory;
if (config.DatabaseType == "MySQL")
{
factory = new MySqlDbFactory();
}
else if (config.DatabaseType == "SQLServer")
{
factory = new SqlServerDbFactory();
}
else
{
throw new ArgumentException("Unsupported database type");
}
IDbConnection connection = factory.CreateConnection();
IDbCommand command = factory.CreateCommand();
connection.Connect();
command.Execute();
connection.Disconnect();
}
}
总结
抽象工厂模式通过提供一个创建一系列相关或相互依赖对象的接口,使得对象的创建更加灵活和一致。虽然它增加了系统的复杂度,但在需要创建多个相关对象的场景中,抽象工厂模式能够显著提高代码的可维护性和扩展性。