Índice do grimório

Padrão 11 · Estruturais

Bridge

combinar formas de arma e essências em dois eixos de variação.

Começar pelo código
Criatura mineral de placas escuras e juntas alaranjadas pressiona uma grade nas ruínas do desfiladeiro.
Cena do capítulo 11 · Bridge

01 · Entenda a escolha

Os fundamentos do padrão.

README.md

11 — Bridge: Armas e essências independentes

Arma é a abstração de alto nível e mantém uma Essencia por composição. Espada e Arco variam forma, gesto e custo-base; Fogo e Gelo variam efeito, custo e restrição de ativação. Nenhuma classe representa um par específico.

Executar

Node 26.10.0, npm 11.19.1, TypeScript 5.9.3, @types/node 26.0.0, lock próprio. Dentro deste diretório:

npm ci --ignore-scripts
npm test
npm start
npm run solution

Da raiz Books:

node book-23/scripts/projetos.mjs 11 install
node book-23/scripts/projetos.mjs 11 check
node book-23/scripts/projetos.mjs 11 capture
node book-23/scripts/projetos.mjs 11 verify

O build limpa dist, compila ES2022/ESM com TypeScript estrito e testa o JavaScript emitido com Node. Nenhum capítulo vizinho é importado. exercise/ fica fora da compilação da solução oficial.

Papéis e arquivos

  • src/armas.ts: Abstraction Arma e Refined Abstractions Espada/Arco.
  • src/contratos.ts: Implementor Essencia, contexto e resultados discriminados.
  • src/essencias.ts: Concrete Implementors EssenciaFogo/EssenciaGelo.
  • src/resultado.ts: combinação dos resultados da forma e da implementação, com limites numéricos.
  • src/direto.ts: alternativa de função para uma forma fixa.
  • src/main.ts: matriz 2×2, troca de essência mantendo a arma e restrição observável.
  • test/ponte.test.ts: matriz, identidade, independência dos resultados, nova implementação e erros.
  • exercise/ e solution/: Escudo e Vento, com cinco pares novos testados.
  • diagram.mmd: fonte editável dos dois eixos; renderização e QA visual na etapa de arte.
  • evidence/: stdout real, testes, manifesto e execução em cópia isolada.

Comportamento e contrato entre os eixos

O custo-base da Espada é 1 e seu gesto é corte; o Arco custa 2 e produz disparo. Fogo custa 3 e acrescenta calor; Gelo custa 4 e acrescenta frio. Com núcleo seco, os quatro pares produzem custos 4, 5, 5 e 6. Os efeitos são dados de resultado ordenados como gesto da forma → efeito da essência.

Nesta versão fictícia, fogo não ativa com núcleo molhado e gelo pode ativar nesse contexto. Um bloqueio devolve estado bloqueado, motivo, custo zero e lista vazia de efeitos; o gesto não é declarado executado. Em caso ativo, o resultado tem estado executado, forma, essência, custo e efeitos. O custo não é descontado de nenhum estoque ou reserva: é um índice de contabilização do ensaio, sem unidade física.

trocarEssencia() muda explicitamente a referência guardada na mesma arma. O teste prova a identidade da arma, a referência exata da essência injetada e que outra arma usando a essência anterior conserva seu vínculo. Não se reconstrói nem se altera a essência anterior. A troca não modifica valores de resultados já entregues.

Cada execução das implementações fornecidas cria um resultado e uma lista de efeitos novos e congelados. Os dados são strings/números, sem outro nível mutável nessa saída. O contexto não é guardado na arma. As essências fornecidas não acumulam estado, mas o contrato não garante pureza de implementações externas: uma essência pode ter seu próprio estado, efeitos ou falhas. Exceções são propagadas, sem retorno de sucesso ou mudança automática de essência.

Custos ativos e sua soma precisam ser inteiros seguros não negativos; zero é válido para uma essência de teste. Valor inválido ou soma fora da faixa segura lança erro. A validação se limita ao contrato numérico deste modelo, não é um validador genérico de JSON, uma verificação física de armas ou um mecanismo de segurança.

Extensões, alternativas e custos

Adicionar Vento e Escudo requer uma classe por eixo e testes das combinações relevantes. Não se edita Espada, Arco, Fogo ou Gelo. A independência tem uma condição: a nova implementação precisa atender Essencia e as formas precisam usar o contrato combinado. Um recurso novo que exija outra capacidade pode forçar mudanças desse contrato; Bridge não garante compatibilidade universal.

Dois eixos acrescentam tipos, dependências e combinações a verificar. Se só uma forma existe e apenas a essência varia, empunharEspadaDireta() compõe a essência por uma função; o teste compara seu resultado ao da Espada. Não é necessário criar uma hierarquia para uma segunda dimensão sem pressão real de evolução.

Adapter reconcilia interfaces existentes que não atendem ao contrato esperado. Aqui formas e essências foram projetadas para cooperar desde o início por uma interface comum. Strategy costuma encapsular uma política ou algoritmo substituível em um contexto. Bridge separa dois eixos de abstrações e implementações que precisam evoluir; poder trocar um objeto em execução é uma característica estrutural compartilhada, não a definição da intenção.

As regras de fogo, gelo e custo são convenções novas do projeto, não propriedades químicas ou físicas. O código não conduz um ataque real, testa material, preserva uma ponte ou garante segurança de transporte. Não há inferência de ganho de desempenho ou economia de memória. Testes e hashes ligam a saída às fontes executadas; não substituem auditoria técnica independente ou aprovação do autor.

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.

src/main.tsTypeScript
import { Arco, Espada } from "./armas.js";
import { EssenciaFogo, EssenciaGelo } from "./essencias.js";

for (const Forma of [Espada, Arco]) {
  for (const essencia of [new EssenciaFogo(), new EssenciaGelo()]) {
    const resultado = new Forma(essencia).empunhar({ nucleoMolhado: false });
    console.log(`${resultado.forma} + ${resultado.essencia}: ${resultado.estado} | custo ${resultado.custo} | ${resultado.efeitos.join(" -> ")}`);
  }
}

const fogo = new EssenciaFogo();
const gelo = new EssenciaGelo();
const espada = new Espada(fogo);
const mesmaArma = espada;
espada.trocarEssencia(gelo);
const trocada = espada.empunhar({ nucleoMolhado: true });
console.log(`Troca: mesma arma ${espada === mesmaArma} | mesma essência injetada ${espada.essenciaAtual() === gelo} | custo ${trocada.custo}`);

const bloqueado = new Espada(fogo).empunhar({ nucleoMolhado: true });
if (bloqueado.estado === "bloqueado") console.log(`Núcleo molhado com fogo: ${bloqueado.estado} | custo ${bloqueado.custo} | ${bloqueado.motivo}`);
A execução do programa é feita localmente.

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.

Espada herda de Arma.
11 · a formas

Esta vista reúne Arma, Espada, Arco. Espada herda de Arma. Arco herda de Arma. Arma: Forma e gesto variam neste eixo. A mesma arma pode trocar a referência de Essencia. Membros exibidos são um recorte; construtores e demais membros podem estar omitidos.

Arma mantém referência a Essencia (referência à essência).
11 · b ponte

Esta vista reúne Arma, Essencia. Arma mantém referência a Essencia (referência à essência). Essencia: Efeito, custo e restrição variam neste eixo. Não há classe por par. Membros exibidos são um recorte; construtores e demais membros podem estar omitidos. e3 · referência à essência

EssenciaFogo realiza Essencia.
11 · c essências

Esta vista reúne Essencia, EssenciaFogo, EssenciaGelo. EssenciaFogo realiza Essencia. EssenciaGelo realiza Essencia. EssenciaFogo: Custo 3. Bloqueia quando nucleoMolhado. EssenciaGelo: Custo 4. Ativa no contexto molhado deste modelo. Membros exibidos são um recorte; construtores e demais membros podem estar omitidos.

04 · Faça sua escolha

Sua vez de conjurar.

exercise/README.md

Exercício — Uma forma e uma essência novas

Adicione Escudo extends Arma, com gesto aparar e custo de forma 2. Adicione também EssenciaVento implements Essencia, com custo de ativação 2 e efeito impulso, sem a restrição de núcleo molhado neste modelo.

Critérios verificáveis:

  • Espada e Arco existentes aceitam a nova essência e produzem custos 3 e 4, respectivamente.
  • Escudo aceita Fogo, Gelo e Vento, com custos 5, 6 e 4.
  • Escudo de fogo preserva o bloqueio com núcleo molhado; trocar sua essência por vento libera o uso sem construir outro escudo.
  • Resultados seguem o contrato comum e preservam efeitos próprios da forma e da essência.
  • Conte classes adicionadas, classes existentes alteradas e combinações cobertas por teste.
  • Explique por que uma função basta quando só há uma forma fixa.

Compare com solution/extensoes.ts e solution/extensoes.test.ts; execute npm run solution. Tentativas em exercise/ ficam fora do build oficial.

Resposta comentada

Foram adicionadas duas classes, uma em cada eixo: Escudo e EssenciaVento. Nenhuma definição das classes existentes precisou ser editada. Os pontos de composição e testes são novos códigos de uso; isso não significa que nenhuma linha de código foi acrescentada ao projeto.

A matriz passa de quatro para nove combinações possíveis entre três formas e três essências. Os quatro pares anteriores são testados no projeto-base e os cinco novos na solução. Não foram criadas classes EscudoDeFogo, EscudoDeGelo ou EspadaDeVento.

Essa independência depende do contrato combinado entre os eixos. Uma essência que exigisse outra capacidade de todas as formas poderia cobrar uma mudança de interface e reconferência das implementações. O padrão não promete encaixe universal de qualquer novo recurso.

Para uma única forma, empunharEspadaDireta() demonstra uma função que compõe a essência sem acrescentar a hierarquia de Arma. Criar dois eixos abstratos sem duas pressões reais de variação acrescentaria indireção desnecessária.

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/11-bridge
npm ci --ignore-scripts --no-audit --no-fund
npm test
npm start

# Depois da sua tentativa
npm run solution
Baixar este projeto completo

Diagrama ampliado