AULA 36 / 61 · ACESSO GRATUITO

Integração duplicação e mudanças

Graciliano TolentinoEngenharia Caracol · Edição 2.0
Nesta aula
  1. Linhas parecidas podem representar decisões distintas
  2. Duas funções concretas antes da decisão
  3. Depois reutilizar a regra já existente
  4. Uma contraprova que impede unificação excessiva
  5. Procedimento para integrar a mudança
  6. Erros que o contador de linhas não detecta
  7. Exercício com resolução
  8. Leitura técnica relacionada

Linhas parecidas podem representar decisões distintas

DRY é uma orientação para evitar a repetição de conhecimento que precisa permanecer coerente. Não é uma ordem para juntar toda sequência de linhas parecidas. Duas funções podem ter aparência diferente e esconder a mesma regra de publicação; duas expressões iguais podem atender necessidades que evoluem de forma independente. A decisão de unificar precisa identificar a regra compartilhada e o custo do acoplamento criado.

Na Oficina, somente casos ativos podem chegar aos consumidores públicos. Essa é uma regra de domínio: mudá-la altera o significado da aplicação. Já a forma de apresentar um título em uma lista e a estrutura de uma opção de seleção são decisões de apresentação. Convém compartilhar a regra pública e manter cada transformação com seu nome. Uma função genérica cheia de parâmetros booleanos pode economizar linhas e tornar a intenção mais difícil de ler.

Duas funções concretas antes da decisão

As funções a seguir são um exercício isolado, não novos exports ou uma nova tela do pacote. Recebem casos válidos com o mesmo contrato do projeto. A primeira produz títulos; a segunda produz opções de uma reserva. Observe onde o conhecimento realmente se repete.

javascript
function titulosDaLista(casos) {
  return casos
    .filter(caso => caso.ativo === true)
    .map(caso => caso.titulo);
}

function opcoesDaReserva(casos) {
  return casos
    .filter(caso => caso.ativo === true)
    .map(caso => ({ valor: caso.id, rotulo: caso.titulo }));
}

As duas funções repetem a política de selecionar ativos. Se uma delas esquecer o filtro, o consumidor poderá divulgar um rascunho. Já os retornos são diferentes por uma razão: o título é texto, enquanto a opção precisa relacionar identificador e rótulo. Unificar esses retornos por um parâmetro “modo” esconderia a diferença sem eliminar a necessidade de compreendê-la.

Depois reutilizar a regra já existente

javascript
import { listarAtivos } from '../src/catalogo.mjs';

function titulosDaLista(casos) {
  return listarAtivos(casos).map(caso => caso.titulo);
}

function opcoesDaReserva(casos) {
  return listarAtivos(casos)
    .map(caso => ({ valor: caso.id, rotulo: caso.titulo }));
}

O módulo de catálogo já possui a política necessária e valida os dados. A extração não precisa criar outro pacote ou uma abstração universal. O ganho é ter um ponto claro para a regra de publicação, preservando nomes e formatos de cada consumidor. Antes de adaptar código real, localize os consumidores existentes e confirme se compartilham essa mesma promessa.

Uma contraprova que impede unificação excessiva

Imagine agora uma rotina de revisão interna cujo contrato é listar os identificadores de todos os registros, incluindo inativos. Seu código pode parecer semelhante ao da lista pública, mas reutilizar listarAtivos mudaria sua finalidade. Essa rotina não existe como funcionalidade da Oficina; é um contraponto fornecido para o exercício de projeto. O fato de dois lugares lerem os mesmos dados não torna suas regras iguais.

Pergunta de decisãoResposta no exemplo
A mudança da regra deve ocorrer nos dois consumidores?Sim, ambos são públicos e seguem REQ-002.
Os formatos precisam se tornar iguais?Não; títulos e opções mantêm contratos distintos.
A regra já tem um dono claro?Sim, listarAtivos em src/catalogo.mjs.
A abstração preserva casos inválidos?Sim, desde que o validador permaneça no caminho compartilhado.
O mesmo helper serve à revisão de todos os registros?Não; seria outra necessidade, com autorização e contrato próprios.

Procedimento para integrar a mudança

  • Escreva qual conhecimento se repete e quais diferenças são intencionais. Não comece pela meta de reduzir linhas.
  • Capture o comportamento atual com exemplos de ativo, inativo, vazio e inválido.
  • Reutilize a regra existente ou extraia uma função pequena com nome de intenção. Preserve os formatos dos consumidores.
  • Integre logo após a mudança e execute npm test e npm run validate dentro de pratica.
  • Examine dependentes, documentação e diff. Registre por que a unificação foi feita e quais contextos ficaram de fora.

Erros que o contador de linhas não detecta

Uma branch longa acumula contratos incompatíveis antes de encontrá-los: integrar cedo reduz o intervalo entre causa e descoberta. DRY automático pode fazer uma tela pública e uma revisão interna compartilharem uma política errada: repare separando os contratos. Um changelog que só diz “refatoração” não mostra o impacto: registre a regra centralizada, as preservações e a verificação feita. Refatorar pretende preservar comportamento, mas essa intenção exige prova adequada; não é necessário inventar uma categoria nova de teste se os testes existentes já protegem o comportamento relevante.

O gate exige testes aplicáveis aprovados, formatos preservados e duplicações ou separações deliberadas com justificativa. Se a extração muda o resultado de um consumidor sem decisão de requisito, ela deixou de ser uma simples preservação de comportamento. Essa diferença precisa ser aceita explicitamente e coberta por prova.

Exercício com resolução

Entrada fornecida: [{id:"a",titulo:"Auditoria",descricao:"Exemplo A",ativo:true},{id:"b",titulo:"Rascunho",descricao:"Exemplo B",ativo:false}]. Calcule os resultados das duas funções e decida se a rotina hipotética que lista todos os IDs deve usar o mesmo filtro.

Ver solução comentada

Resolução: titulosDaLista devolve ["Auditoria"]; opcoesDaReserva devolve [{valor:"a",rotulo:"Auditoria"}]. A rotina interna de todos os IDs espera ["a","b"] e não deve aplicar a política pública. A rubrica exige preservar esses três resultados, justificar a centralização de REQ-002 sem unir formatos e manter inválidos explicitamente rejeitados. Escrever “unificar porque são parecidas” ou “nunca unificar” não demonstra a decisão.

Leitura técnica relacionada

S17: catálogo Refactoring, Extract Function, para nomear e isolar uma intenção. S09: Fowler, Continuous Integration, para integração frequente e verificável. Esses textos apoiam técnicas específicas; a decisão sobre a política pública vem do contrato da Oficina.

Fontes relacionadas

Consulte os limites e as seções de apoio de cada referência.

S17 S09
Conseguiu explicar o que aprendeu?

Tente o exercício antes de consultar a solução. Marque a aula para organizar sua leitura.

A conclusão desta leitura não equivale a certificação ou aceite de um projeto real. Teste os exemplos no escopo indicado e registre as limitações.