Skip to content

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口,用于创建相关或依赖对象的家族,而无需指定它们的具体类。这个模式的目的是使一组相关或依赖的对象在不指定其具体类的情况下能一起使用。

关键点

  1. 抽象工厂(Abstract Factory): 定义一个创建一组相关对象的接口,但不指定具体类。
  2. 具体工厂(Concrete Factory): 实现抽象工厂接口,创建具体产品对象。
  3. 抽象产品(Abstract Product): 为每种产品类型定义一个接口。
  4. 具体产品(Concrete Product): 实现抽象产品接口,提供产品的具体实现。
  5. 客户端(Client): 通过抽象工厂接口创建产品对象,不需要知道具体工厂类。

实现

假设我们有一个 UI 工具包,可以创建按钮和文本框,我们希望提供不同的风格,如 Windows 风格和 Mac 风格。

1. 定义抽象产品

csharp
// 抽象产品 - 按钮
public interface IButton
{
    void Paint();
}

// 抽象产品 - 文本框
public interface ITextBox
{
    void Render();
}

2. 实现具体产品

csharp
// 具体产品 - Windows 按钮
public class WindowsButton : IButton
{
    public void Paint()
    {
        Console.WriteLine("Render a button in Windows style.");
    }
}

// 具体产品 - Windows 文本框
public class WindowsTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("Render a textbox in Windows style.");
    }
}

// 具体产品 - Mac 按钮
public class MacButton : IButton
{
    public void Paint()
    {
        Console.WriteLine("Render a button in Mac style.");
    }
}

// 具体产品 - Mac 文本框
public class MacTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("Render a textbox in Mac style.");
    }
}

3. 创建抽象工厂

csharp
// 抽象工厂
public interface IGUIFactory
{
    IButton CreateButton();
    ITextBox CreateTextBox();
}

4. 实现具体工厂

csharp
// 具体工厂 - Windows 工厂
public class WindowsFactory : IGUIFactory
{
    public IButton CreateButton()
    {
        return new WindowsButton();
    }

    public ITextBox CreateTextBox()
    {
        return new WindowsTextBox();
    }
}

// 具体工厂 - Mac 工厂
public class MacFactory : IGUIFactory
{
    public IButton CreateButton()
    {
        return new MacButton();
    }

    public ITextBox CreateTextBox()
    {
        return new MacTextBox();
    }
}

5. 客户端代码

csharp
class Application
{
    private readonly IButton button;
    private readonly ITextBox textBox;

    public Application(IGUIFactory factory)
    {
        button = factory.CreateButton();
        textBox = factory.CreateTextBox();
    }

    public void Paint()
    {
        button.Paint();
        textBox.Render();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 使用 Windows 风格的组件
        IGUIFactory factory = new WindowsFactory();
        Application app = new Application(factory);
        app.Paint();  // 输出:Render a button in Windows style. Render a textbox in Windows style.

        // 使用 Mac 风格的组件
        factory = new MacFactory();
        app = new Application(factory);
        app.Paint();  // 输出:Render a button in Mac style. Render a textbox in Mac style.
    }
}

解释

  1. 抽象产品接口:定义了产品的通用接口,如 IButtonITextBox
  2. 具体产品类:实现了产品接口的具体类,如 WindowsButtonWindowsTextBoxMacButtonMacTextBox
  3. 抽象工厂接口:定义了创建产品对象的方法,如 IGUIFactory
  4. 具体工厂类:实现了抽象工厂接口的具体类,如 WindowsFactoryMacFactory,它们负责创建具体产品对象。
  5. 客户端代码:通过抽象工厂接口创建产品对象,并使用这些对象进行操作。

优点

  • 分离接口与实现:将具体类的实现与客户端代码分离,客户端只需要知道抽象接口。
  • 易于扩展:增加新的产品家族时,只需添加新的具体工厂类和具体产品类,不需要修改现有代码。
  • 一致性:确保同一工厂创建的产品属于同一个家族,具有一致的风格或主题。

缺点

  • 复杂性增加:引入更多的接口和类,增加了系统的复杂性。
  • 扩展困难:如果需要增加新的产品类型,抽象工厂接口和所有的具体工厂类都需要修改。