Fábrica abstrata C#

Resumo : neste tutorial, você aprenderá como usar o padrão de fábrica abstrato C# para criar famílias de objetos dependentes sem especificar suas classes concretas.

Introdução ao padrão de design C# Abstract Factory

O Abstract Factory é um padrão de design criacional que fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.

O padrão Abstract Factory é útil quando você precisa criar famílias de objetos relacionados que funcionem perfeitamente uns com os outros como um grupo e tenham comportamento consistente.

Digamos que você esteja construindo um kit de ferramentas de UI para criar aplicativos móveis multiplataforma. E você deseja criar widgets de UI, como botões e campos de texto, que funcionem nas plataformas iOS e Android.

Nesse caso, você pode usar o padrão Abstract Factory para criar uma interface abstrata de fábrica que defina métodos para construir cada um desses widgets. E você então implementa essa interface com fábricas concretas que criam widgets em cada plataforma.

A vantagem de usar o padrão Abstract Factory é que ele encapsula a criação de objetos e separa a lógica de criação de objetos do restante do seu código. Isso permite alterar facilmente a implementação dos objetos sem afetar a base de código.

Por exemplo, você deseja oferecer suporte a plataformas móveis adicionais além de iOS e Android.

Diagrama UML abstrato de fábrica

O diagrama UML a seguir ilustra o padrão de design de fábrica abstrato:

Padrão de design de fábrica abstrato C#

O padrão Abstract Factory envolve os seguintes participantes:

  • Abstract Factory: Esta é a interface que declara um conjunto de métodos de fábrica para criar produtos abstratos. É responsável por definir as operações que criam as famílias de objetos relacionados.
  • Fábrica Concreta: São as classes que implementam a interface abstrata da fábrica e criam famílias de objetos relacionados. Cada fábrica de concreto é responsável por criar uma variante diferente da família de produtos.
  • Produto abstrato: Esta é a interface que declara um conjunto de operações que os produtos concretos devem implementar. Define um tipo de produto, mas não fornece detalhes de implementação.
  • Produto Concreto: São as classes que implementam a interface abstrata do produto e fornecem uma implementação específica do produto. Cada fábrica de concreto cria uma variante diferente da família de produtos.
  • Cliente: Esta é a classe que usa as interfaces abstratas de fábrica e produto abstrato para criar famílias de objetos relacionados. O código do cliente não sabe quais produtos concretos está criando, apenas que pertencem à mesma família de produtos.

O Cliente usa a interface abstrata de fábrica para criar uma família de objetos relacionados.

A fábrica abstrata cria as fábricas concretas que criam os produtos concretos. Além disso, o Cliente utiliza a interface abstrata do produto para criar produtos concretos, sem conhecer os detalhes específicos da implementação.

Exemplos de padrões de design abstratos de fábrica em C#

O programa C# a seguir demonstra como usar o padrão de design Abstract Factory criando diferentes famílias de widgets para plataformas iOS e Android:

using static System.Console;

namespace AbstractFactory;

// Widget abstract class
public abstract class Widget
{
    public abstract void Render();
}

// Button widget for iOS platform
public class IOSButton : Widget
{
    public override void Render()
    {
        WriteLine("Rendering iOS button...");
    }
}

// TextField widget for iOS platform
public class IOSTextField : Widget
{
    public override void Render()
    {
        WriteLine("Rendering iOS text field...");
    }
}

// Button widget for Android platform
public class AndroidButton : Widget
{
    public override void Render()
    {
        WriteLine("Rendering Android button...");
    }
}

// TextField widget for Android platform
public class AndroidTextField : Widget
{
    public override void Render()
    {
        WriteLine("Rendering Android text field...");
    }
}

// Widget factory interface
public interface IWidgetFactory
{
    public Widget CreateButton();
    public Widget CreateTextField();
}

// iOS widget factory
public class IOSWidgetFactory : IWidgetFactory
{
    public Widget CreateButton()
    {
        return new IOSButton();
    }

    public Widget CreateTextField()
    {
        return new IOSTextField();
    }
}

// Android widget factory
public class AndroidWidgetFactory : IWidgetFactory
{
    public Widget CreateButton()
    {
        return new AndroidButton();
    }

    public Widget CreateTextField()
    {
        return new AndroidTextField();
    }
}

// App (Client) that to create and use widgets
public class App
{
    private readonly IWidgetFactory factory;

    public App(IWidgetFactory factory)
    {
        this.factory = factory;
    }

    public void RenderUI()
    {
        Widget button = factory.CreateButton();
        Widget textField = factory.CreateTextField();

        button.Render();
        textField.Render();
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        WriteLine("Enter the platform (ios or android): ");
        var platform = ReadLine().ToLower();

        IWidgetFactory factory;
        if (platform == "ios")
        {
            factory = new IOSWidgetFactory();
        }
        else if (platform == "android")
        {
            factory = new AndroidWidgetFactory();
        }
        else
        {
            WriteLine("Invalid platform entered.");
            return;
        }

        var app = new App(factory);
        app.RenderUI();
    }
}
Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina uma classe abstrata chamada Widgetque represente um widget genérico. A Widgetclasse possui um método abstrato Render()que renderiza o widget em uma plataforma específica:

public abstract class Widget
{
    public abstract void Render();
}Linguagem de código:  C#  ( cs )

Em segundo lugar, defina duas classes concretas, IOSButtone para criação e na plataforma iOS. Ambas as classes herdam da classe:IOSTextFieldButtonTextFieldWidget

// Button widget for iOS platform
public class IOSButton : Widget
{
    public override void Render()
    {
        WriteLine("Rendering iOS button...");
    }
}

// TextField widget for iOS platform
public class IOSTextField : Widget
{
    public override void Render()
    {
        WriteLine("Rendering iOS text field...");
    }
}Linguagem de código:  C#  ( cs )

Terceiro, defina duas classes concretas semelhantes, AndroidButtone , para criação de widgets na plataforma Android. Essas classes também herdam da classe.AndroidTextFieldButtonTextFieldWidget

// Button widget for Android platform
public class AndroidButton : Widget
{
    public override void Render()
    {
        WriteLine("Rendering Android button...");
    }
}

// TextField widget for Android platform
public class AndroidTextField : Widget
{
    public override void Render()
    {
        WriteLine("Rendering Android text field...");
    }
}Linguagem de código:  C#  ( cs )

Quarto, defina uma interface IWidgetFactorypara criação Buttonde TextFieldwidgets:

// Widget factory interface
public interface IWidgetFactory
{
    public Widget CreateButton();
    public Widget CreateTextField();
}Linguagem de código:  C#  ( cs )

Quinto, defina uma classe chamada IOSWidgetFactoryque implemente o IWidgetFactory. O IOSWIdgetFactoryé responsável pela criação Buttonde TextFieldwidgets na plataforma iOS:

// iOS widget factory
public class IOSWidgetFactory : IWidgetFactory
{
    public Widget CreateButton()
    {
        return new IOSButton();
    }

    public Widget CreateTextField()
    {
        return new IOSTextField();
    }
}Linguagem de código:  C#  ( cs )

Sexto, defina a AndroidWidgetFactoryclasse que implementa a IWidgetFactoryinterface. O AdroidWidgetFactoryresponsável pela criação Buttonde TextFieldwidgets na plataforma Android:

// Android widget factory
public class AndroidWidgetFactory : IWidgetFactory
{
    public Widget CreateButton()
    {
        return new AndroidButton();
    }

    public Widget CreateTextField()
    {
        return new AndroidTextField();
    }
}Linguagem de código:  C#  ( cs )

Sétimo, defina a Appclasse que pega uma instância da IWidgetFactoryinterface e a utiliza para criar e usar widgets:

// App (Client) that to create and use widgets
public class App
{
    private readonly IWidgetFactory factory;

    public App(IWidgetFactory factory)
    {
        this.factory = factory;
    }

    public void RenderUI()
    {
        Widget button = factory.CreateButton();
        Widget textField = factory.CreateTextField();

        button.Render();
        textField.Render();
    }
}Linguagem de código:  C#  ( cs )

Oitavo, o Main()método da Programclasse solicita que o usuário insira a plataforma para a qual deseja criar widgets e, em seguida, usa a fábrica concreta apropriada para criar os widgets. Em seguida, ele cria um Appobjeto e passa a fábrica para renderizar o widget para ele:

public class Program
{
    public static void Main(string[] args)
    {
        WriteLine("Enter the platform (ios or android): ");
        var platform = ReadLine().ToLower();

        IWidgetFactory factory;
        if (platform == "ios")
        {
            factory = new IOSWidgetFactory();
        }
        else if (platform == "android")
        {
            factory = new AndroidWidgetFactory();
        }
        else
        {
            WriteLine("Invalid platform entered.");
            return;
        }

        var app = new App(factory);
        app.RenderUI();
    }
}Linguagem de código:  C#  ( cs )

O seguinte mostra a saída do programa quando você insere iOS como plataforma:

Enter the platform (ios or android):
ios
Rendering iOS button...
Rendering iOS text field...Linguagem de código:  texto simples  ( texto simples )

Se você inserir o Android como plataforma, verá a saída como esta:

Enter the platform (ios or android):
android
Rendering Android button...
Rendering Android text field...Linguagem de código:  texto simples  ( texto simples )

Veja como as classes e interfaces do programa são mapeadas para os participantes do padrão Abstract Factory:

  • Fábrica Abstrata: A IWidgetFactoryinterface.
  • Fábrica de Concreto: As aulas IOSWidgetFactorye AndroidWidgetFactory.
  • Produto abstrato: A Widgetclasse abstrata.
  • Produto Concreto: As classes IOSButton, IOSTextField, AndroidButtone AndroidTextField.
  • Cliente: A Appturma.

Resumo

  • O padrão Abstract Factory é um padrão de design criacional que fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
  • O padrão Abstract Factory é útil quando um sistema precisa ser independente da maneira como os objetos que ele cria são gerados ou compostos.
  • O padrão Abstract Factory promove acoplamento fraco, permitindo que um cliente crie objetos sem precisar conhecer as classes específicas de objetos que ele cria.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *