Padrão 01 · Criacionais
Factory Method
variar a criação do mensageiro mantendo a operação comum de envio.
Começar pelo código
01 · Entenda a escolha
Os fundamentos do padrão.
01 — Factory Method: Mensageiros da guilda
Uma rotina de envio precisa continuar válida quando a criação do mensageiro muda. O projeto demonstra o Factory Method canônico: subclasses sobrescrevem criarMensageiro(), e CriadorDeNotificacoes.enviar() usa o produto por meio da interface Mensageiro.
Executar isoladamente
Requer Node 26.10.0 e npm 11.19.1 (se houver nvm: nvm use). Dentro deste diretório:
npm ci --ignore-scripts
npm test
npm start
npm run solution
npm test limpa dist, compila fontes/testes/solução com TypeScript estrito e executa node:test. exercise/ fica fora do build, separado da resposta. Nenhum outro capítulo é importado.
Arquivos e responsabilidades
src/contratos.ts: pedido, comprovante, produto e porta de correio.src/criadores.ts: Creator, operação comum e Concrete Creators.src/mensageiros.ts: Concrete Products.src/correio-em-memoria.ts: simulador local com histórico observável.src/cliente.ts: cliente que depende do criador abstrato.src/main.ts: composição e demonstração.test/: preservação do contrato, limites e falha do correio.exercise/README.md: enunciado e critérios.solution/: extensão de corvo, execução e testes.diagram.mmd: relações editáveis correspondentes ao código-base.evidence/: saídas reais, resultados e manifesto SHA-256.
Contrato e limites
enviar() remove espaços externos de destino e mensagem, rejeita strings vazias e só então cria um mensageiro. Um envio válido gera exatamente um registro local. O comprovante e a lista consultada não expõem mutação do histórico interno. Uma falha do correio é propagada; não há fallback automático nem retentativa.
O correio é síncrono, local e em memória: registro não significa recebimento por pessoa, transporte de rede, persistência, criptografia ou confirmação remota. IDs são sequenciais por instância, não globais. Os parâmetros têm tipos estáticos; a aplicação não valida JSON arbitrário nem é uma API pública pronta para produção. TypeScript não tem final: não sobrescrever enviar() é contrato de extensão, não bloqueio da linguagem.
Alternativa e custo
Se só for preciso escolher um rótulo de canal, uma função como correio.entregar(canal, pedido) resolve com menos classes. A hierarquia serve aqui para estudar uma operação herdada cujo ponto de criação varia, com produtos substituíveis. Adiciona classes, arquivos e acoplamento por herança. O exemplo reduz os transportes ao mínimo para observar o mecanismo, sem alegar que uma hierarquia se paga neste simulador.
Uma Simple Factory centralizaria uma escolha de produto (por exemplo, em uma função com discriminador). Aqui a operação chama um método sobrescrito pelas subclasses. Abstract Factory trata de famílias de produtos relacionados; não se distingue apenas pela quantidade de objetos produzidos.
O exercício amplia os canais sem editar a operação comum. A solução de corvo continua uma simulação; não mede latência nem capacidade de transporte.
02 · Leia o mecanismo
O feitiço, linha por linha.
Comece por src/main.ts para ver o programa em uso. Explore os contratos, a implementação e os testes no seletor de arquivos.
import { avisarGuilda } from "./cliente.js";
import { CorreioEmMemoria } from "./correio-em-memoria.js";
import { CriadorDeCristal, CriadorDePergaminho } from "./criadores.js";
const correio = new CorreioEmMemoria();
const pedido = {
destino: "Posto da Ponte",
mensagem: "Fechem a comporta antes da terceira badalada.",
};
// Ponto de composição: aqui se escolhem os criadores concretos.
for (const criador of [new CriadorDeCristal(correio), new CriadorDePergaminho(correio)]) {
const recibo = avisarGuilda(criador, pedido);
console.log(`#${recibo.id} | ${recibo.canal} | ${recibo.destino} | ${recibo.mensagem}`);
}
console.log(`Entregas registradas: ${correio.listarEntregas().length}`);
03 · Revele as conexões
A estrutura por trás da magia.
Veja os papéis e suas relações. Amplie cada vista para ler atributos, métodos e conexões com calma.
Esta vista reúne CriadorDeNotificacoes, CriadorDeCristal, CriadorDePergaminho, Mensageiro. CriadorDeCristal herda de CriadorDeNotificacoes. CriadorDePergaminho herda de CriadorDeNotificacoes. CriadorDeNotificacoes depende de Mensageiro (enviar usa produto). CriadorDeNotificacoes: enviar valida e normaliza; chama criarMensageiro; delega entregar. Membros exibidos são um recorte; construtores e demais membros podem estar omitidos. e5 · enviar usa produto
Esta vista reúne CriadorDeCristal, CriadorDePergaminho, Mensageiro, MensageiroDeCristal, MensageiroDePergaminho. MensageiroDeCristal realiza Mensageiro. MensageiroDePergaminho realiza Mensageiro. CriadorDeCristal depende de MensageiroDeCristal (cria). CriadorDePergaminho depende de MensageiroDePergaminho (cria). Membros exibidos são um recorte; construtores e demais membros podem estar omitidos. e6 · cria e7 · cria
Esta vista reúne CriadorDeNotificacoes, MensageiroDeCristal, MensageiroDePergaminho, Correio, CorreioEmMemoria. MensageiroDeCristal mantém referência a Correio. MensageiroDePergaminho mantém referência a Correio. CriadorDeNotificacoes mantém referência a Correio. CorreioEmMemoria realiza Correio. Membros exibidos são um recorte; construtores e demais membros podem estar omitidos.
04 · Faça sua escolha
Sua vez de conjurar.
Exercício — O canal de corvo
Implemente MensageiroDeCorvo e CriadorDeCorvo em arquivos novos. O produto deve implementar Mensageiro; o criador deve estender CriadorDeNotificacoes e sobrescrever somente criarMensageiro().
Critérios verificáveis:
avisarGuilda()continua idêntica e recebe o novo criador.- Um envio válido aparece no correio com canal
corvo, destino e mensagem corretos. - Espaços externos são removidos pela operação comum herdada.
- Destino ou mensagem vazios lançam o erro existente e não geram entrega.
- Nenhum
switch, parâmetro discriminador ou alteração emsrc/criadores.tsé necessário.
Compare sua solução com ../solution/corvo.ts e os testes em ../solution/corvo.test.ts. Para praticar, mantenha seus arquivos em exercise/ e compile com uma configuração própria: esse diretório não participa do build oficial, evitando colisões com a resposta.
A solução usa herança para variar a criação, preservando a operação. Se o problema fosse apenas escolher um rótulo de canal, passar esse rótulo a uma função seria suficiente; a hierarquia aqui torna explícito o mecanismo do Factory Method, sem afirmar que é necessária para todo sistema de mensagens.
Compare depois da sua tentativa.
A resposta e seus testes estão na pasta solution/. O sucesso dos testes fornecidos confirma essa resposta; sua tentativa precisa estar incluída na compilação para ser avaliada.
Do estudo à prática
Experimente localmente.
Node 26.10.0 · npm 11.19.1 · TypeScript 5.9.3
Execute os comandos dentro da pasta deste projeto. O lock instala o compilador local. Os programas não são executados no navegador.
cd book-23/code/01-factory-method npm ci --ignore-scripts --no-audit --no-fund npm test npm start # Depois da sua tentativa npm run solutionBaixar este projeto completo