# Guia de Referência: Abstract Factory (Criacional)


Este guia orienta a aplicação do padrão **Abstract Factory** em projetos de software. **Objetivo:** Criar famílias coerentes de objetos relacionados sem expor classes concretas ao código cliente. O padrão deve ser usado somente quando as forças do problema o justificarem.

---

## 1. Problema que resolve

O sistema precisa trocar um conjunto inteiro de componentes compatíveis (por tema, fornecedor, plataforma, ambiente ou protocolo) sem misturar variantes.

### Sinais no código/arquitetura
- Vários objetos precisam ser criados em conjunto e devem pertencer à mesma família.
- Há condicionais repetidas por plataforma/tenant/provedor.
- Misturar implementações de famílias diferentes pode gerar inconsistências.

## 2. Quando usar
- UI multiplataforma/temas com famílias de widgets.
- Gateways de infraestrutura por provedor, como storage + fila + cache.
- Clientes de APIs por versão/protocolo em que request builder e parser precisam combinar.

## 3. Quando NÃO usar
- Quando você só precisa criar um único produto variável.
- Quando as famílias mudam mais rapidamente que os produtos e a interface da fábrica ficaria instável.
- Quando DI/configuração simples já resolve.

## 4. Estrutura e participantes
- AbstractFactory: operações para criar cada tipo de produto.
- ConcreteFactory: cria uma família específica.
- AbstractProducts: contratos dos produtos.
- ConcreteProducts: membros concretos e compatíveis da família.
- Client: usa apenas fábrica e contratos.

## 5. Procedimento de implementação
1. Mapeie quais produtos sempre variam em conjunto.
2. Defina um contrato para cada produto.
3. Defina uma fábrica com métodos para todos os produtos da família.
4. Implemente uma fábrica por família.
5. Injete uma única fábrica no cliente e proíba criação concreta fora do composition root.

## 6. Exemplo mental

`CloudFactory` cria `Storage`, `Queue` e `Mailer`. `AwsFactory` retorna a família AWS; `LocalFactory` retorna implementações locais para testes.

## 7. Benefícios esperados
- Garante compatibilidade entre produtos da mesma família.
- Troca de ambiente/provedor em um ponto só.
- Isola classes concretas.

## 8. Custos e trade-offs
- Adicionar um novo tipo de produto exige mudar a interface de todas as fábricas.
- Pode ser pesado para famílias pequenas.

## 9. Encaixe com Clean Architecture e SOLID

A interface da fábrica pode pertencer à aplicação; fábricas concretas e SDKs ficam em infraestrutura. O composition root escolhe a família.

**Regras para a IA:**
- Dependa de abstrações quando a variação justificar uma fronteira.
- Não faça o domínio importar SDKs, frameworks, banco de dados ou UI.
- Mantenha cada participante com responsabilidade coesa.
- Prefira composição quando ela reduzir acoplamento; não crie hierarquias artificiais.
- Registre a decisão arquitetural quando o padrão afetar muitos módulos.

## 10. Caminho de refatoração

Útil quando um mesmo `if provider == ...` se repete para construir diversos componentes relacionados.

Ao refatorar um sistema existente:
1. Proteja o comportamento atual com testes.
2. Faça passos pequenos e reversíveis.
3. Introduza primeiro a abstração/contrato.
4. Migre um fluxo por vez.
5. Remova código antigo apenas após equivalência comportamental comprovada.

## 11. Estratégia de testes

Use uma fábrica fake para testes de aplicação; crie testes de contrato que garantam que cada família entrega produtos compatíveis.

Checklist mínimo:
- [ ] caminho feliz
- [ ] entradas/estados de limite
- [ ] erros e falhas de dependências
- [ ] comportamento de cada implementação concreta
- [ ] teste de contrato quando houver múltiplas implementações
- [ ] teste de integração apenas onde a fronteira externa for relevante

## 12. Padrões relacionados
- Factory Method
- Prototype
- Builder

## 13. Perguntas de diagnóstico para a IA

1. Qual aspecto do sistema realmente varia?
2. Essa variação já está causando duplicação, condicionais ou acoplamento?
3. Uma função/composição simples resolveria com menos abstrações?
4. O padrão reduz o custo de uma mudança concreta que já é provável?
5. Qual é o custo de introduzir novas classes, indireção e configuração?
6. Como a decisão será testada e observada em produção?

## 14. Prompt pronto

```text
Você é o arquiteto do projeto. Avalie se o padrão **Abstract Factory** é adequado para o problema abaixo.

Contexto: [DESCREVA o sistema, stack/arquitetura, estado atual e o problema observado]
Objetivo: [DESCREVA o resultado esperado ao avaliar ou aplicar este padrão]
Restrições: [DESCREVA prazo, legado, performance, testes, compatibilidade e o que não pode mudar]

Antes de codificar:
1. Identifique as forças que justificam ou rejeitam Abstract Factory.
2. Compare pelo menos uma alternativa mais simples e um padrão relacionado (Factory Method, Prototype, Builder).
3. Se o padrão for justificado, mostre participantes, dependências e fluxo.
4. Preserve Clean Architecture/SOLID: regras centrais não dependem de infraestrutura.
5. Implemente incrementalmente, com testes.
6. Ao final, liste trade-offs e sinais de overengineering.

Não aplique o padrão apenas porque foi solicitado; rejeite-o se não houver variação/complexidade que o justifique.
```

### Como preencher os campos

- **Contexto:** descreva o tipo de sistema, stack/versões, arquitetura atual, onde a mudança acontece e o comportamento relevante já existente.
- **Objetivo:** descreva o resultado observável que deve existir ao final, não apenas a tecnologia que você quer usar.
- **Restrições:** informe o que não pode mudar, compatibilidade, prazo, segurança, acessibilidade, performance, legado, dependências e limites de escopo.

### Exemplo preenchido

```text
Contexto: Aplicação suporta dois kits visuais completos e cada kit possui botão, campo e diálogo compatíveis.
Objetivo: Trocar a família inteira de componentes sem misturar implementações de temas diferentes.
Restrições: Famílias devem permanecer coerentes; não usar se só um componente varia.
```


## 15. Critério de aceite

A aplicação de **Abstract Factory** só está concluída quando:
- [ ] o problema que motivou o padrão está explicitamente documentado;
- [ ] o código cliente depende do contrato correto, não de detalhes acidentais;
- [ ] adicionar a variação-alvo exige menos mudanças que antes;
- [ ] testes protegem a extensão/refatoração;
- [ ] não houve vazamento de infraestrutura para o núcleo;
- [ ] a solução ficou mais compreensível para manutenção, não apenas “mais orientada a padrões”.

## 16. Base Conceitual e Relações

- Catálogo Refactoring.Guru em português — escopo de 22 padrões.
- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gamma, Helm, Johnson e Vlissides) — intenção, aplicabilidade, participantes, consequências e relações entre padrões.
- Guias de Clean Architecture, princípios de design, refatoração e código limpo deste pacote.
