定义
抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式强调的是对象族的创建,而不是单一对象的创建。
用例写法
假设我们有一个场景,需要根据不同的平台(如 Windows 和 MacOS)创建不同的用户界面组件(如按钮和文本框)。
// 用户界面组件接口
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
):根据配置信息选择合适的工厂类,并使用工厂类创建具体的用户界面组件,然后调用其渲染方法。
用途
- 创建一系列相关对象:当需要创建一系列相关或相互依赖的对象时,使用抽象工厂模式可以确保这些对象的一致性。
- 解耦对象的创建和使用:客户端代码只需要依赖抽象工厂接口,不需要知道具体的产品类,从而降低了耦合度。
- 支持多平台:适用于需要在不同平台上创建不同版本的对象的场景。
优点
- 易于交换产品族:可以在运行时动态地切换不同的产品族,只需更换工厂对象即可。
- 支持开闭原则:增加新的产品族时,只需要添加新的具体工厂类,不需要修改现有的代码,符合开闭原则。
- 高度模块化:每个产品族的创建逻辑都封装在对应的工厂类中,模块化程度高。
缺点
- 系统复杂度增加:引入了更多的接口和类,系统结构变得更复杂。
- 增加代码量:每增加一个新的产品族,都需要增加相应的工厂类和产品类。
- 产品族扩展困难:如果需要增加新的产品类型,必须修改所有的工厂类,这违反了开闭原则。
适用场景
- 产品族多:当系统中有多个产品族,且每个产品族中的产品需要一起使用时。
- 多平台支持:需要在不同平台上创建不同版本的对象时。
- 对象创建逻辑复杂:对象的创建逻辑较为复杂,需要集中管理和控制时。
实际开发中的应用
1. 多平台用户界面框架
假设我们正在开发一个多平台用户界面框架,需要根据不同的操作系统创建不同的用户界面组件。
// 用户界面组件接口
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. 数据库操作框架
假设我们正在开发一个数据库操作框架,需要根据不同的数据库类型创建不同的数据访问对象。
// 数据访问接口
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();}
}
总结
抽象工厂模式通过提供一个创建一系列相关或相互依赖对象的接口,使得对象的创建更加灵活和一致。虽然它增加了系统的复杂度,但在需要创建多个相关对象的场景中,抽象工厂模式能够显著提高代码的可维护性和扩展性。