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:
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 Widget
que represente um widget genérico. A Widget
classe 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, IOSButton
e para criação e na plataforma iOS. Ambas as classes herdam da classe:IOS
TextField
Button
TextField
Widget
// 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, AndroidButton
e , para criação de widgets na plataforma Android. Essas classes também herdam da classe.Android
TextField
Button
TextField
Widget
// 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 IWidgetFactory
para criação Button
de TextField
widgets:
// Widget factory interface
public interface IWidgetFactory
{
public Widget CreateButton();
public Widget CreateTextField();
}
Linguagem de código: C# ( cs )
Quinto, defina uma classe chamada IOSWidgetFactory
que implemente o IWidgetFactory
. O IOSWIdgetFactory
é responsável pela criação Button
de TextField
widgets 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 AndroidWidgetFactory
classe que implementa a IWidgetFactory
interface. O AdroidWidgetFactory
responsável pela criação Button
de TextField
widgets 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 App
classe que pega uma instância da IWidgetFactory
interface 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 Program
classe 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 App
objeto 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
IWidgetFactory
interface. - Fábrica de Concreto: As aulas
IOSWidgetFactory
eAndroidWidgetFactory
. - Produto abstrato: A
Widget
classe abstrata. - Produto Concreto: As classes
IOSButton
,IOSTextField
,AndroidButton
eAndroidTextField
. - Cliente: A
App
turma.
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.