Abstract Factory
O Abstract Factory é um padrão de projeto criacional que oferece uma interface para criar famílias de objetos relacionados (ou dependentes) sem especificar suas classes concretas.
Em vez de o código do cliente instanciar diretamente new BotaoWindows() ou new BotaoMac(), ele recebe uma fábrica (ex.: WindowsFactory ou MacFactory) capaz de produzir um conjunto coerente de componentes.
Ideia central: “Se eu escolhi a família Windows, tudo que eu criar deve ser Windows (botão, checkbox, etc.).”
Problema que ele resolve
Seção intitulada “Problema que ele resolve”Imagine uma aplicação que suporta múltiplos temas/ambientes, por exemplo:
- Interface Windows
- Interface macOS
Você já tem componentes como:
- Botão
- Checkbox
Se o cliente criar objetos diretamente, surgem problemas comuns:
- Acoplamento: o código fica cheio de
new ...Windows/new ...Mac. - Mistura indevida de famílias: dá para acabar com
BotaoWindows+CheckboxMacno mesmo contexto. - Baixa extensibilidade: adicionar uma nova família (ex.: Linux) exige revisar muitos pontos do código.
Solução (a ideia do padrão)
Seção intitulada “Solução (a ideia do padrão)”O Abstract Factory propõe:
- Definir interfaces de produto (ex.:
Button,Checkbox). - Definir uma interface de fábrica com métodos para criar cada produto (ex.:
createButton(),createCheckbox()). - Criar fábricas concretas para cada família (ex.:
WindowsFactory,MacFactory) que produzem produtos compatíveis entre si. - O cliente recebe uma fábrica e cria tudo por ela, sem conhecer as classes concretas.
Estrutura (participantes)
Seção intitulada “Estrutura (participantes)”- AbstractFactory: declara métodos de criação (um por tipo de produto).
- ConcreteFactory: implementa os métodos para uma família específica.
- AbstractProduct: interface de cada produto (ex.:
Button). - ConcreteProduct: implementação do produto para a família (ex.:
WindowsButton). - Client: usa apenas interfaces (factory + products), sem
newde concretos.
Exemplo didático (GUI: Windows e macOS) — Java
Seção intitulada “Exemplo didático (GUI: Windows e macOS) — Java”1) Produtos abstratos
Seção intitulada “1) Produtos abstratos”ButtoneCheckboxsão interfaces (contrato).- O cliente só conhece esses contratos.
2) Famílias concretas
Seção intitulada “2) Famílias concretas”WindowsButtoneWindowsCheckboxMacButtoneMacCheckbox
3) Fábricas
Seção intitulada “3) Fábricas”GUIFactory(abstract)WindowsFactory/MacFactory(concrete)
Código (enxuto, mas completo)
Seção intitulada “Código (enxuto, mas completo)”// Produtos abstratosinterface Button { void render();}
interface Checkbox { void toggle();}
// Produtos Windowsclass WindowsButton implements Button { @Override public void render() { System.out.println("Renderizando botão no estilo Windows"); }}
class WindowsCheckbox implements Checkbox { @Override public void toggle() { System.out.println("Alternando checkbox no estilo Windows"); }}
// Produtos macOSclass MacButton implements Button { @Override public void render() { System.out.println("Renderizando botão no estilo macOS"); }}
class MacCheckbox implements Checkbox { @Override public void toggle() { System.out.println("Alternando checkbox no estilo macOS"); }}
// Fábrica abstratainterface GUIFactory { Button createButton(); Checkbox createCheckbox();}
// Fábricas concretas (famílias)class WindowsFactory implements GUIFactory { @Override public Button createButton() { return new WindowsButton(); } @Override public Checkbox createCheckbox() { return new WindowsCheckbox(); }}
class MacFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); } @Override public Checkbox createCheckbox() { return new MacCheckbox(); }}
// Clienteclass Application { private final Button button; private final Checkbox checkbox;
Application(GUIFactory factory) { this.button = factory.createButton(); this.checkbox = factory.createCheckbox(); }
void run() { button.render(); checkbox.toggle(); }}
// Bootstrappublic class Main { public static void main(String[] args) { GUIFactory factory = chooseFactoryByOS("windows"); // simulado new Application(factory).run(); }
static GUIFactory chooseFactoryByOS(String os) { if ("mac".equalsIgnoreCase(os)) return new MacFactory(); return new WindowsFactory(); }}O que observar:
- O
Applicationnão sabe o que éWindowsButtonnemMacButton. - Ao trocar
WindowsFactoryporMacFactory, a aplicação muda de família inteira (coerente).
Quando usar
Seção intitulada “Quando usar”Use Abstract Factory quando:
- Você precisa criar famílias de objetos que devem ser compatíveis entre si.
- Você quer isolar a criação de objetos do restante do código.
- Você precisa trocar “tema/ambiente/driver/fornecedor” sem reescrever o cliente.
Exemplos típicos:
- GUI multi-plataforma (Windows/macOS/Linux)
- Conectores para bancos (MySQL/Postgres) com famílias de objetos (conexão, comando, transação)
- Integrações com provedores (AWS/Azure/GCP) com serviços correspondentes
Vantagens
Seção intitulada “Vantagens”- Garante consistência entre produtos da mesma família.
- Reduz acoplamento do cliente com classes concretas.
- Facilita trocar famílias (ex.: Windows → macOS) com poucas mudanças.
Desvantagens
Seção intitulada “Desvantagens”- Aumenta o número de classes/interfaces.
- Se você adicionar um novo tipo de produto (ex.:
Slider), precisa alterar a fábrica abstrata e todas as fábricas concretas.
Comparação rápida com outros padrões
Seção intitulada “Comparação rápida com outros padrões”- Factory Method: cria um tipo de produto via herança/polimorfismo; bom quando há um foco em um produto principal.
- Abstract Factory: cria famílias de produtos (botão + checkbox + etc.), garantindo compatibilidade.
- Builder: foca em construir um objeto complexo passo a passo; não é sobre famílias compatíveis.
Checklist mental (para identificar)
Seção intitulada “Checklist mental (para identificar)”Pergunte:
- “Tenho variações (Windows/Mac) e múltiplos produtos (botão/checkbox) que precisam combinar?”
- “Quero escolher uma família em tempo de execução/configuração e o restante deve seguir essa escolha?”
Se sim, Abstract Factory é um forte candidato.
Leitura de referência
Seção intitulada “Leitura de referência”- Refactoring.Guru — Abstract Factory (pt-br): https://refactoring.guru/pt-br/design-patterns/abstract-factory