ATLAS / PADRÕES DE PROJETO / FABRÍCIO CASTRO
Um padrão não é regra.
É uma alternativa.
Design Patterns nomeiam estruturas recorrentes, mas não substituem engenharia de requisitos, domínio e testes. Este Atlas apresenta os 23 padrões clássicos da Gang of Four, sua finalidade, quando ajudam, quando atrapalham e o custo de abstrair antes da necessidade.
01 / PROBLEMA → FORÇAS → DECISÃO
Um nome conhecido não torna o projeto melhor.
Um padrão descreve uma resposta reutilizável a forças recorrentes, não um conjunto de arquivos obrigatórios. No JavaScript e no TypeScript, funções, objetos literais e módulos nativos já resolvem parte do que exigia classes e hierarquias em outros ecossistemas.
Qual mudança queremos tornar segura?
Um fluxo de compras varia por alçada, por estado e por integração externa. Primeiro separe regra de negócio, transição de estado e protocolo remoto. Pergunte qual parte muda independentemente, quem a controla e qual teste preserva o comportamento.
Experimento: comece com funções e condicionais legíveis; introduza a estrutura maior quando houver divergência real de algoritmos, testabilidade ou acoplamento.
O padrão diminui ou desloca a complexidade?
Meça esforço de alteração, legibilidade da navegação entre arquivos, dependências, estado compartilhado, falhas e testes. Um projeto com cinquenta classes para três regras pode ser pior que um único módulo explícito.
Consequência: registrar alternativa rejeitada, trade-off e gatilho para refatorar. Mais padrões no código não são evidência de maior qualidade.
Precisão histórica: o livro Design Patterns: Elements of Reusable Object-Oriented Software (Gamma, Helm, Johnson e Vlissides, 1994) apresenta 23 padrões. O catálogo online atual da Refactoring.Guru lista 22 e omite Interpreter. Aqui ele é mantido por fidelidade ao inventário clássico, com a ressalva de que a utilidade de cada padrão depende do idioma da linguagem.
02 / INVENTÁRIO GANG OF FOUR
Padrões criacionais. Como construir objetos sem acoplamento acidental?
Os 5 padrões desta família são decisões possíveis, não páginas automaticamente publicadas. Em cada item, compare a intenção com o contexto que justifica sua adoção e com uma alternativa mais econômica.
Factory Method
Mecanismo: Subclasses especializam a criação de um produto exigido pelo fluxo.
Usar quando: Uma hierarquia de criadores precisa instanciar produtos distintos sem amarrar a lógica à classe concreta.
Evitar quando: Um mapa de factories ou uma função de fábrica resolve quando não existe motivo para herança.
Abstract Factory
Mecanismo: Cria famílias coerentes de objetos relacionados sob contrato comum.
Usar quando: Um mesmo contexto deve trocar integralmente provedores ou famílias de componentes compatíveis.
Evitar quando: Uma família única e estável não justifica múltiplas interfaces de fábrica.
Builder
Mecanismo: Organiza construção por etapas quando há combinações e validações complexas.
Usar quando: Construções de muitos parâmetros possuem ordem, defaults ou variantes que pedem legibilidade.
Evitar quando: Um objeto literal com validação clara é melhor para parâmetros simples.
Prototype
Mecanismo: Produz novos objetos a partir de instâncias existentes e de sua configuração.
Usar quando: A cópia preserva configuração relevante sem reconstrução onerosa.
Evitar quando: Clonar entidades de domínio pode duplicar identidade e estado mutável indevidamente.
Singleton
Mecanismo: Restringe uma instância e o ponto de acesso dentro de um escopo.
Usar quando: Recursos verdadeiramente únicos têm ciclo de vida controlado explicitamente.
Evitar quando: Estado global escondido e dependências implícitas prejudicam isolamento e testes.
03 / INVENTÁRIO GANG OF FOUR
Padrões estruturais. Como compor responsabilidades e adaptar contratos?
Os 7 padrões desta família são decisões possíveis, não páginas automaticamente publicadas. Em cada item, compare a intenção com o contexto que justifica sua adoção e com uma alternativa mais econômica.
Adapter
Mecanismo: Traduz a interface de um colaborador para um contrato que o domínio espera.
Usar quando: ERP ou SDK externo oferece nomes, erros e formatos incompatíveis com o modelo interno.
Evitar quando: Não introduzir uma camada apenas para renomear chamadas estáveis sem preservar contrato.
Bridge
Mecanismo: Separa abstração e implementação para variar duas dimensões independentemente.
Usar quando: Diferentes canais e mecanismos precisam evoluir sem multiplicar subclasses combinatórias.
Evitar quando: Uma única dimensão fixa geralmente permite composição direta mais simples.
Composite
Mecanismo: Trata objetos simples e composições hierárquicas sob contrato comum.
Usar quando: Estruturas de árvore representam operações sobre folhas e grupos de modo uniforme.
Evitar quando: Não impor hierarquia se coleção plana ou consulta relacional atende melhor.
Decorator
Mecanismo: Acrescenta comportamento envolvendo um colaborador sem alterar seu contrato.
Usar quando: Tracing, cache ou regras opcionais podem ser compostos em camadas explícitas.
Evitar quando: Empilhar wrappers dificulta ordem, exceções e depuração; middleware pode servir melhor.
Facade
Mecanismo: Expõe operação simplificada sobre subsistemas com múltiplas responsabilidades.
Usar quando: Uma ação de aplicação coordena tarefas técnicas sem vazar detalhes ao consumidor.
Evitar quando: Fachada gigante pode esconder limites de domínio e virar serviço onisciente.
Flyweight
Mecanismo: Compartilha estado imutável repetido para reduzir custo por objeto.
Usar quando: Instâncias numerosas mantêm parte intrínseca idêntica medida como gargalo.
Evitar quando: Otimização prematura pode misturar estado compartilhado e por solicitação.
Proxy
Mecanismo: Intermedia acesso preservando a interface do objeto representado.
Usar quando: Controle remoto, cache ou autorização de recurso pede interposição transparente.
Evitar quando: O proxy não pode esconder efeitos de rede, latência ou falha que alterem semântica.
04 / INVENTÁRIO GANG OF FOUR
Padrões comportamentais. Como distribuir regras, decisões e colaboração?
Os 11 padrões desta família são decisões possíveis, não páginas automaticamente publicadas. Em cada item, compare a intenção com o contexto que justifica sua adoção e com uma alternativa mais econômica.
Chain of Responsibility
Mecanismo: Encadeia tratadores que processam ou encaminham uma solicitação.
Usar quando: Há etapas opcionais ou configuráveis de validação/autorização com ordem explícita.
Evitar quando: Pipelines opacos tornam difícil saber qual regra negou a ação.
Command
Mecanismo: Representa uma solicitação como objeto/dado com executor e resultado.
Usar quando: Fila de tarefas, undo ou trilha de ações demanda transportar ou persistir intenção.
Evitar quando: Um método direto é suficiente quando não há necessidade de encapsular execução.
Interpreter
Mecanismo: Representa e avalia uma gramática restrita de expressões.
Usar quando: Uma linguagem pequena, estável e bem delimitada de regras precisa de AST.
Evitar quando: Gramáticas extensas ou linguagem de regras de segurança exigem parser consolidado e validação.
Iterator
Mecanismo: Expõe travessia de coleções sem conhecer sua implementação interna.
Usar quando: Consumidores percorrem estruturas heterogêneas sob ordem controlada.
Evitar quando: No JavaScript, iteráveis/generators nativos normalmente substituem classes extras.
Mediator
Mecanismo: Centraliza coordenação de objetos que não devem se referenciar diretamente.
Usar quando: Participantes mudam interações cruzadas e precisam de um mediador compreensível.
Evitar quando: Concentrar todas as regras em um mediador enorme recria acoplamento central.
Memento
Mecanismo: Registra estado suficiente para restauração sem expor estrutura interna.
Usar quando: Undo local ou checkpoints precisam reverter estado consistente.
Evitar quando: Não substituir event sourcing, logs de auditoria ou backups transacionais por snapshots ad hoc.
Observer
Mecanismo: Notifica assinantes sobre mudança de um objeto em memória.
Usar quando: Eventos locais de UI ou processos desencadeiam efeitos desacoplados.
Evitar quando: Não presume persistência, ordenação ou entrega confiável entre serviços.
State
Mecanismo: Muda comportamento válido segundo o estado interno de um objeto.
Usar quando: Cada estado controla transições próprias e exige rejeição clara das ilegais.
Evitar quando: Um enum com poucas transições estáveis pode permanecer um switch legível.
Strategy
Mecanismo: Troca algoritmo/política por composição sob interface comum.
Usar quando: Regras de cálculo variam por contrato, canal ou região sem mudar o caso de uso.
Evitar quando: Uma única variação trivial não exige hierarquia de classes nem abstrações extras.
Template Method
Mecanismo: Define esqueleto de algoritmo com pontos de extensão por herança.
Usar quando: Variações compartilham ordem invariável e subclasses substituem passos restritos.
Evitar quando: Composição e funções de alta ordem são mais flexíveis quando a hierarquia é instável.
Visitor
Mecanismo: Acrescenta operações sobre tipos de uma hierarquia de objetos.
Usar quando: Tipos mudam pouco e operações novas surgem frequentemente.
Evitar quando: Se novos tipos aparecem com frequência, alterar todos os visitors custa caro.
05 / ESTUDO DE CASO COM CÓDIGO E TESTES
Strategy e State parecem parecidos. Respondem a perguntas distintas.
Strategy troca a política de decisão segundo configurações confiáveis. State restringe eventos conforme a situação atual do objeto. Ambos podem coexistir em um sistema sem garantir autorização, transação ou isolamento de dados.
Quem pode aprovar?
Para um valor pequeno, a política padrão aceita aprovador habilitado. Para uma compra de maior valor, outra política exige função sênior. O algoritmo troca por composição, enquanto a aplicação ainda verifica identidade, organização e conflito de interesses.
O que pode acontecer agora?
O pedido em rascunho pode ser enviado. O pedido pendente pode ser aprovado ou recusado. Um pedido aprovado não aceita novo evento de aprovação. O estado governa transições, não a política de alçada.
CAPÍTULO INDEPENDENTE / EXECUÇÃO DIDÁTICA
Compare código, testes e contraexemplos concretos.
O estudo completo apresenta modelos TypeScript, testes de negação cross-tenant, autoaprovação, alçada e transições ilegais, além da alternativa com condicionais simples. Nenhum desses testes substitui PostgreSQL real.
06 / ESCALA E LIMITES
GoF, Clean, DDD e Outbox não são sinônimos.
Um padrão de projeto organiza colaboração entre objetos. Uma arquitetura descreve fronteiras de responsabilidades e atributos de qualidade. Um padrão de integração lida com falhas entre sistemas. Não compare nomes de níveis diferentes como se resolvessem a mesma necessidade.
- 01Observer não é mensageria distribuída
Um evento em memória não assegura durabilidade, ordem entre processos, reentrega e idempotência. Para integração ERP, defina contrato, outbox/reconciliação e testes de falha em outro nível de arquitetura.
- 02Adapter não corrige falta de autorização
Traduzir o contrato de uma API permite proteger o modelo interno de mudanças externas. Não substitui autenticação, controle de alçada, validação de tenant e limites transacionais.
- 03Singleton não é gerência segura de estado global
Dependências globais mutáveis acoplam testes e execuções concorrentes. Ciclos de vida declarados no framework ou módulos imutáveis podem atender melhor à necessidade.
- 04Pattern ≠ classe por obrigação
Uma função pura pode implementar uma estratégia. Um objeto literal pode ser fábrica; um iterador nativo dispensa uma hierarquia GoF completa. A intenção e o trade-off importam mais que a forma.
PRÉ-REQUISITO / FRONTEIRAS
A arquitetura explica onde cada padrão pertence.
Antes de inserir abstrações em um sistema real, avalie contexto, invariantes, qualidade, dependências e consequências.
07 / REFERÊNCIAS E AUTORIA
Estudar os padrões nas fontes. Confrontá-los com o código atual.
As explicações e o diagrama desta página são originais e resumem intenções de forma contextual. Não reproduzem código ou ilustrações de terceiros. O exemplo de compras é fictício, não um projeto de cliente comprovadamente entregue.
Gamma, Helm, Johnson e Vlissides — Design Patterns.
Referência histórica dos 23 GoF, organizada em criação, estrutura e comportamento. É importante distinguir a taxonomia original da forma idiomática de implementar suas ideias em TypeScript.
Refactoring.Guru — padrões de projeto.
Material explicativo disponível em português, incluindo comparações de intenções. Seu catálogo online contém 22 itens; Interpreter é tratado aqui a partir do inventário original.
TypeScript Handbook — narrowing, interfaces e objetos.
O estudo de Strategy e State deve ser confrontado com recursos nativos da linguagem e seus trade-offs, sem copiar implementações antigas literalmente.
Prova antes de abstração.
Os testes do estudo demonstram comportamento de funções puras. Nenhuma conclusão sobre isolamento transacional ou qualidade de produção deve ser inferida sem execução de banco, revisão de segurança e métricas apropriadas.
Estado editorial: guia implementado em branch. Build, execução de testes, revisão de acessibilidade e publicação ainda precisam de evidência vinculada ao commit.