Padrão de projeto: Abstract Factory
- #.NET
- #.NET C#
- #Design Patterns
O padrão de projeto Abstract Factory é um padrão criacional que permite a criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas. Ele fornece uma interface para criar objetos, mas permite que as subclasses decidam qual classe concreta será instanciada. O padrão é útil quando um sistema precisa ser independente de como seus produtos são criados, compostos ou representados.
Características principais:
- Objetivo: Fornecer uma interface para criar objetos de famílias relacionadas sem acoplar o código às classes concretas.
- Uso comum: Sistemas que precisam trabalhar com várias famílias de produtos, como interfaces gráficas (UI), onde diferentes componentes (botões, caixas de diálogo) variam conforme a plataforma (Windows, Mac, Linux).
- Vantagem: Torna o sistema flexível para adicionar novas "famílias de produtos" sem modificar o código que usa essas famílias.
Exemplo prático em C#:
Vamos construir um exemplo simples de um sistema de criação de componentes de interface gráfica (UI) para dois temas: Tema Clássico e Tema Moderno. Cada tema terá dois componentes: Botão e Janela.
Interface para Botão e Janela (Produtos abstratos):
// Produto abstrato para Botão
public interface IBotao
{
void Renderizar();
}
// Produto abstrato para Janela
public interface IJanela
{
void Abrir();
}
Implementações concretas para Tema Clássico:
// Botão concreto do Tema Clássico
public class BotaoClassico : IBotao
{
public void Renderizar()
{
Console.WriteLine("Renderizando botão clássico.");
}
}
// Janela concreta do Tema Clássico
public class JanelaClassica : IJanela
{
public void Abrir()
{
Console.WriteLine("Abrindo janela clássica.");
}
}
Implementações concretas para Tema Moderno:
// Botão concreto do Tema Moderno
public class BotaoModerno : IBotao
{
public void Renderizar()
{
Console.WriteLine("Renderizando botão moderno.");
}
}
// Janela concreta do Tema Moderno
public class JanelaModerna : IJanela
{
public void Abrir()
{
Console.WriteLine("Abrindo janela moderna.");
}
}
Interface da Fábrica Abstrata:
// Fábrica abstrata para criar os produtos relacionados
public interface IFabricaUI
{
IBotao CriarBotao();
IJanela CriarJanela();
}
Fábricas concretas (uma para cada tema):
// Fábrica concreta para criar componentes do Tema Clássico
public class FabricaUIClassica : IFabricaUI
{
public IBotao CriarBotao()
{
return new BotaoClassico();
}
public IJanela CriarJanela()
{
return new JanelaClassica();
}
}
// Fábrica concreta para criar componentes do Tema Moderno
public class FabricaUIModerna : IFabricaUI
{
public IBotao CriarBotao()
{
return new BotaoModerno();
}
public IJanela CriarJanela()
{
return new JanelaModerna();
}
}
Cliente (Uso do Abstract Factory):
public class Aplicacao
{
private readonly IBotao _botao;
private readonly IJanela _janela;
public Aplicacao(IFabricaUI fabrica)
{
_botao = fabrica.CriarBotao();
_janela = fabrica.CriarJanela();
}
public void RenderizarInterface()
{
_botao.Renderizar();
_janela.Abrir();
}
}
Testando o código:
class Program
{
static void Main(string[] args)
{
// Criando uma interface com o tema clássico
IFabricaUI fabricaClassica = new FabricaUIClassica();
Aplicacao appClassica = new Aplicacao(fabricaClassica);
appClassica.RenderizarInterface();
Console.WriteLine();
// Criando uma interface com o tema moderno
IFabricaUI fabricaModerna = new FabricaUIModerna();
Aplicacao appModerna = new Aplicacao(fabricaModerna);
appModerna.RenderizarInterface();
}
}
Saída:
Renderizando botão clássico.
Abrindo janela clássica.
Renderizando botão moderno.
Abrindo janela moderna.
Explicação:
- Fábrica Abstrata (IFabricaUI): Define métodos para criar famílias de produtos relacionados (
CriarBotao
eCriarJanela
), permitindo a criação de objetos sem especificar suas classes concretas. - Fábricas Concretas (FabricaUIClassica e FabricaUIModerna): Implementam a fábrica abstrata e retornam instâncias específicas dos produtos (
BotaoClassico
,JanelaClassica
,BotaoModerno
,JanelaModerna
). - Cliente (Aplicacao): Usa a fábrica abstrata para trabalhar com os objetos, sem depender de implementações concretas.
Esse exemplo mostra como o padrão Abstract Factory permite criar famílias de objetos relacionados (botões e janelas) com flexibilidade, possibilitando a troca de temas (clássico ou moderno) sem modificar o código do cliente.