O que inclui uma estimativa de reescrita de software?
Uma estimativa de reescrita de software deve medir código, ramificações, integrações, dados, operações e superfície de testes com provas.

Uma estimativa de reescrita deve descrever a incerteza do comportamento, não premiar quem contou o repositório mais depressa. As linhas de código importam porque alguém terá de as inspecionar e substituir, mas a contagem de linhas é apenas um dado de entrada. A profundidade das ramificações, as integrações externas, a semântica dos dados, os trabalhos operacionais e a superfície disponível para testes de paridade costumam alterar mais a estimativa do que o tamanho bruto.
Já vi motores de faturação compactos demorarem mais a substituir do que aplicações enormes de relatórios. O sistema pequeno escondia regras em ramos aninhados, guardava estados intermédios em tabelas que ninguém tinha documentado e chamava serviços que se comportavam de modo diferente no fecho do mês. O maior repetia padrões CRUD simples e tinha registos de pedidos limpos. Qualquer estimativa que comece e termine em "300.000 linhas" coloca uma etiqueta precisa num trabalho que não foi medido.
O que a contagem de linhas consegue dizer
A contagem de linhas é uma medida útil do volume a inspecionar, mas não mede sozinha a dificuldade de uma reescrita. Ainda assim, uma equipa precisa de uma contagem reproduzível, porque o tamanho do repositório, o número de ficheiros e as linhas executáveis acabam misturados durante as conversas comerciais.
Defina a regra de contagem antes de comparar propostas. Separe, no mínimo, o código-fonte de produção, o código gerado, as dependências de terceiros, os testes, o código da base de dados, o controlo de trabalhos, a configuração e os comentários. Um milhão de linhas que inclui stubs de cliente gerados é um sistema diferente de um milhão de linhas de COBOL, JCL, SQL e copybooks escritas à mão. Se quem faz a estimativa não mostrar essas categorias, o total não pode ser auditado.
Um comando simples de inventário dá aos responsáveis de engenharia uma primeira verificação. cloc não é uma ferramenta de estimativa, mas produz uma estrutura estável que pode ser executada novamente quando as exclusões mudam:
cloc . --exclude-dir=vendor,node_modules,dist --by-file --json --out=cloc.json
jq '.SUM | {blank, comment, code}' cloc.json
O resultado tem este formato:
{"blank":18420,"comment":27116,"code":263904}
Guarde também a saída ao nível dos ficheiros. Ela permite que um revisor encontre subsistemas concentrados, blocos gerados que escaparam às exclusões e linguagens que a primeira passagem ignorou. Num ambiente mainframe, conte JCL, copybooks, saídas em assembler, procedimentos SQL, mapas de ecrã e definições do agendador juntamente com a linguagem da aplicação. Podem conter pouca lógica de negócio, mas definem como o sistema arranca, para, troca ficheiros e recupera.
A contagem de linhas funciona melhor como denominador. Defeitos por mil linhas, ramos por módulo, chamadas de integração por mil linhas e testes que cobrem cada capacidade de negócio dizem algo. Um preço criado pela multiplicação das linhas por uma taxa universal não diz. A mesma linha pode ser a declaração de um campo, um getter gerado ou o ramo que decide se uma conta recebe juros depois de um acerto retroativo.
As ramificações medem o comportamento a preservar
As ramificações importam porque cada caminho de decisão pode codificar um comportamento observável diferente. Conte os pontos de decisão, meça como se combinam e identifique onde o estado ou os dados externos alteram o resultado. Um módulo plano com vinte validações independentes é mais fácil de compreender do que uma rotina onde dez decisões estão aninhadas e partilham estado mutável.
A complexidade ciclomática é um primeiro sinal razoável. Thomas McCabe definiu-a a partir do grafo de fluxo de controlo, normalmente resumida, para uma rotina ligada, como o número de decisões mais um. O número não prevê sozinho o esforço. Indica quantos caminhos independentes existem, enquanto o aninhamento indica a dificuldade que uma pessoa ou ferramenta terá para os seguir.
O setor confunde regularmente a contagem de ramos com a profundidade das ramificações. Suponha que duas rotinas contêm oito decisões cada uma. Na primeira, oito cláusulas de guarda rejeitam registos inválidos e depois é feito um cálculo. Na segunda, elegibilidade, jurisdição, classe de produto, data de vigência, estado de exceção e ajustes anteriores estão aninhados em seis níveis. Ambas podem receber uma pontuação ciclomática semelhante. A segunda costuma exigir mais fixtures, uma reconstrução de estado mais cuidadosa e mais revisão, porque uma condição muda o significado de todas as condições abaixo dela.
Peça uma distribuição, não uma média. A média de um repositório esconde as cinco rotinas que controlam movimentos de dinheiro ou o funcionamento de uma fábrica. Os grupos úteis incluem rotinas acima de um limite ciclomático acordado, profundidade máxima de aninhamento, fan-in, fan-out e a quantidade de código alcançável a partir de pontos de entrada com consequências importantes. O limite deve assinalar trabalho de inspeção, não declarar que o código é "mau".
Pergunte também se a análise resolve despacho dinâmico, chamadas geradas, macros e regras controladas pela base de dados. A análise estática pode ignorar um nome de programa lido de uma tabela, um CALL de COBOL montado em tempo de execução ou um evento de formulário VB6 ligado fora da rotina visível. Um relatório honesto marca as arestas não resolvidas. Não trata silenciosamente os dados em falta no grafo como baixa complexidade.
A complexidade altera uma estimativa através do trabalho de prova. Cada caminho com consequências precisa de uma entrada conhecida, uma saída esperada e um estado inicial relevante. Se os rastos de produção cobrirem a maioria dos caminhos, a equipa pode obter casos da realidade. Se os registos só capturarem um código de estado final, alguém terá de reconstruir as decisões através da leitura do código e de execuções direcionadas. A quantidade de trabalho muda, mesmo com código idêntico.
As integrações externas criam risco nas fronteiras
As integrações externas merecem um inventário próprio porque uma reescrita falha mais vezes nas fronteiras do que na sintaxe. Uma "integração" inclui mais do que uma API HTTP. Inclui ficheiros colocados em armazenamento partilhado, filas de mensagens, sessões de terminal, ligações de bases de dados, fluxos de impressora, SMTP, eventos do agendador, comandos de shell, fornecedores de identidade, dispositivos físicos e pessoas que movem manualmente resultados entre sistemas.
Conte cada contrato distinto e registe direção, protocolo, proprietário, frequência, autenticação, formato dos dados, comportamento em caso de falha e substituto de teste. Dez endpoints atrás de um cliente de serviço documentado podem ser mais simples do que um único ficheiro noturno de largura fixa cujo proprietário saiu e cujos registos rejeitados aparecem na caixa de correio de um operador.
A pergunta incómoda é se uma integração pode ser exercitada fora da produção. Uma sandbox do fornecedor com dados artificiais pode não reproduzir a limitação de pedidos, a ordenação, a renovação do certificado ou o comportamento de fim do dia. Uma base de dados partilhada pode não ter uma cópia de teste. Um parceiro pode aceitar apenas uma janela de certificação. Essas restrições pertencem à estimativa porque determinam a rapidez com que a equipa consegue saber se a substituição está correta.
Inventarie os dois lados de cada fronteira. Chamar uma API é apenas metade do contrato. O sistema antigo pode repetir pedidos com determinados códigos, suprimir duplicados, depender da ordem das respostas ou escrever um registo de reconciliação depois de um timeout. As interfaces de ficheiros transportam regras semelhantes na nomenclatura, codificação, fins de linha, trailers, ficheiros vazios, entregas parciais e novas execuções. Tratá-las como "uma integração SFTP" elimina os pormenores com maior probabilidade de travar a entrada em produção.
A responsabilidade é um dado para o calendário, não uma nota organizacional. Registe quem pode responder a perguntas, emitir credenciais, aprovar uma regra de firewall, fornecer uma amostra e observar um teste. Se não existir um proprietário, atribua um preço explícito à descoberta e à contingência. Não esconda esse risco numa margem geral do projeto, porque os responsáveis precisam da opção de nomear um proprietário antes de assinar.
Uma estimativa credível distingue a implementação da integração da prova da integração. Escrever um cliente novo pode ser rotina. Provar que se comporta corretamente durante repetições, entradas malformadas, duplicados, entregas tardias e indisponibilidade do parceiro concentra a incerteza. Peça os dois números.
A superfície de testes define o nível de confiança
A superfície de testes é o conjunto de comportamentos observáveis que podem ser acionados e comparados, não o número de ficheiros de teste no repositório. Os testes unitários existentes só ajudam quando verificam comportamento que o sistema novo tem de preservar. Uma suite cheia de mocks pode descrever a estrutura antiga de classes e dizer pouco sobre faturas, lançamentos, mensagens ou ficheiros na fronteira do sistema.
Meça a superfície por capacidade de negócio e ponto de observação. Para cada ponto de entrada, registe que entradas podem ser reproduzidas, que estado inicial pode ser recriado, que saídas podem ser capturadas e que efeitos secundários podem ser comparados. Inclua respostas de API, alterações na base de dados, mensagens enviadas, ficheiros gerados, lançamentos contabilísticos, permissões, tempos que afetam a ordem e erros visíveis para o operador.
O tráfego de produção gravado é especialmente útil porque contém combinações que ninguém se lembrou de pôr num plano de testes. Mesmo assim, precisa de regras de tratamento. Segredos e dados pessoais podem exigir ocultação, os pedidos podem depender de um estado expirado e a repetição de um comando pode acionar um efeito externo. Um rasto é uma prova, não é automaticamente uma fixture segura.
Cobertura tem pelo menos três significados numa reescrita, e as propostas costumam trocá-los sem aviso. A cobertura do código pergunta que instruções ou ramos antigos foram executados. A cobertura de requisitos pergunta que regras documentadas têm testes. A cobertura de comportamento pergunta que combinações de entrada e saída visíveis externamente foram comparadas. Uma reescrita pode relatar cobertura alta do código e perder uma convenção de ficheiros não documentada da qual as operações dependem. Para a aceitação, a cobertura de comportamento tem o maior peso.
Pergunte como serão classificadas as diferenças. Algumas são defeitos. Outras expõem um erro antigo que o negócio quer preservar temporariamente. Outras resultam de timestamps, identificadores gerados, ordem, arredondamento, configuração regional ou dependências não deterministas e precisam de normalização. Sem uma política de comparação acordada, uma percentagem de paridade não tem significado, porque uma equipa pode melhorá-la ignorando campos difíceis.
A estimativa deve declarar o nível de prova proposto. Uma ferramenta interna de consulta com poucas consequências pode precisar de casos representativos e aceitação dos utilizadores. Um motor de lançamentos pode exigir repetição de tráfego gravado, fixtures focadas nos ramos, totais de reconciliação e injeção controlada de falhas. A confiança pretendida muda o trabalho. "Reescrever o mesmo código" não define esse objetivo.
A semântica dos dados pode pesar mais do que a aplicação
O trabalho com dados cresce com o significado, o histórico e o acoplamento, não apenas com o número de linhas. Uma base de dados pequena pode conter colunas sobrecarregadas, códigos implícitos, chaves estrangeiras quebradas, regras temporais e procedimentos armazenados que transportam a maior parte do comportamento do sistema. Uma grande tabela de eventos onde só se acrescentam dados pode ser movida sem problemas porque o seu contrato é simples.
Estime separadamente a tradução do esquema, a limpeza de dados, a execução da migração, a reconciliação e a reversão. São trabalhos diferentes. Traduzir um campo decimal compactado para um tipo numérico de Postgres é mecânico. Decidir se vazio, zero e um valor sentinela significam todos "desconhecido" exige provas no código e nos dados de produção. A reconciliação prova depois que o mapeamento escolhido preservou saldos e contagens.
O estado oculto é especialmente caro. Os programas antigos comunicam muitas vezes através de tabelas de trabalho, registos de controlo, ficheiros de sequência, variáveis de ambiente ou convenções de nomes, em vez de chamadas explícitas. Um trabalho batch escreve um byte de estado; um trabalho posterior interpreta-o como autorização para ignorar uma conta. Um diagrama de esquema não mostra esse comportamento. A análise de dependências deve incluir leituras e escritas, ordem dos trabalhos e duração do estado intermédio.
O volume continua a importar, mas peça distribuições e limites operacionais. O pico de alteração diária, a maior partição, a largura do registo, a retenção, os registos tardios e a interrupção permitida importam mais do que o total histórico de linhas. Uma migração que cabe numa janela de manutenção tem um plano diferente de uma que precisa de captura de alterações e reconciliações repetidas enquanto os dois sistemas funcionam.
Não aceite "migração da base de dados incluída" como medição. Pergunte que tabelas têm mapeamentos de origem para destino, que significados de campos continuam por resolver, que rotinas armazenadas passam para serviços, quantas regras de reconciliação existem e como funciona a reversão depois de o sistema novo receber escritas. Quem não consegue responder atribuiu um preço a uma suposição.
O código operacional pertence à fronteira do sistema
Agendadores, scripts de implementação, manuais do operador, regras de acesso, monitorização e procedimentos de recuperação fazem parte do comportamento da aplicação. Deixá-los fora da estimativa produz uma substituição que passa uma demonstração, mas não consegue fechar um dia de negócio.
Os ambientes batch tornam isto evidente. JCL ou CL podem definir dependências, execução condicional, alocação de conjuntos de dados, pontos de reinício e notificações. O código da aplicação pode parecer simples enquanto a rede de trabalhos transporta o verdadeiro fluxo de controlo. Nos sistemas de desktop, scripts de instalação, definições do registo, pastas partilhadas e tarefas agendadas desempenham o mesmo papel. Nos monólitos web, entradas cron e ações manuais de administração costumam preencher a lacuna.
Peça uma contagem de trabalhos agendados, gatilhos, unidades de implementação, definições específicas do ambiente, funções, alertas, relatórios e intervenções documentadas do operador. Ligue-os depois às capacidades de negócio. Uma lista sem grafo de dependências não consegue mostrar se um trabalho falhado reinicia em segurança ou se uma credencial bloqueia quinze processos.
O comportamento de recuperação precisa de testes diretos. Interrompa um batch depois de escrever metade da saída. Entregue a mesma mensagem duas vezes. Faça uma dependência atingir o timeout depois de aceitar um pedido. Restaure um snapshot da base de dados enquanto ainda há trabalho na fila. O sistema antigo pode conter anos de respostas práticas para estes casos, mesmo que ninguém as tenha escrito. A reescrita tem de preservar essas respostas ou substituí-las por decisões aprovadas pelo negócio.
Esta área também expõe uma recomendação popular, mas errada: "modernizar as operações depois da paridade funcional". As equipas gostam dela porque parece reduzir o âmbito. Na verdade, adia a descoberta dos requisitos de reinício, ordem, acesso e monitorização até o novo desenho estar consolidado. Os dashboards cosméticos podem esperar. O comportamento que mantém dinheiro, registos e trabalhos consistentes depois de uma falha não pode.
A prontidão operacional deve aparecer como trabalho medido, com responsáveis e provas de aceitação. Se uma proposta a tratar como uma linha curta junto da implementação, o preço está incompleto.
As mudanças de arquitetura precisam de duas estimativas
Modernizar a arquitetura e preservar o comportamento são frentes relacionadas, mas não são o mesmo trabalho. Atribua-lhes preços separados para que uma decisão de desenho não reduza silenciosamente a prova prometida. Uma fronteira de serviço pode melhorar a responsabilidade e a implementação, mas também cria contratos, modos de falha e decisões de consistência de dados que o monólito tratava com chamadas locais e uma transação.
As estimativas de transliteração parecem muitas vezes baratas porque mapeiam uma unidade antiga para uma nova. Essa abordagem pode preservar estruturas acidentais, estado global e restrições de implementação obsoletas. Uma reescrita séria deve identificar capacidades e escolher fronteiras adequadas ao ambiente de destino. A estimativa tem de incluir a análise necessária para separar essas capacidades, não apenas a produção de sintaxe equivalente.
O erro oposto é a ambição de arquitetura sem orçamento para o comportamento. Uma proposta pode prometer serviços, eventos, um cliente novo e uma base de dados nova enquanto reserva pouco tempo para descobrir o que o sistema existente realmente faz. Essa equipa tomará decisões de desenho limpas contra um modelo incompleto. O resultado pode ficar bem num diagrama e estar errado durante um reembolso, uma nova execução ou uma falha parcial.
Peça dois mapas ligados. O mapa de comportamento liga os pontos de entrada antigos, as decisões, as mudanças de estado e as saídas. O mapa de destino atribui esses comportamentos a componentes novos e indica que acoplamento antigo desaparecerá. Cada responsabilidade movida precisa de provas dos dois lados: o que prova o comportamento antigo e o que prova o contrato novo. Assim, os responsáveis distinguem uma modernização deliberada de uma conversão de ficheiros com nomes novos de diretórios.
O comportamento transversal exige atenção especial durante a decomposição. Autenticação, autorização, âmbito da transação, idempotência, arredondamento, configuração regional, registos de auditoria e mapeamento de erros podem aparecer em muitos módulos antigos porque não existia uma fronteira central. Contar cada cópia como uma função separada aumenta a estimativa. Contar a preocupação uma vez e ignorar as suas muitas variantes observáveis reduz a estimativa em excesso. Meça os comportamentos distintos e depois desenhe a implementação partilhada.
Os requisitos de desempenho pertencem à mesma comparação. Não copie todas as características de tempo acidentais do sistema antigo, mas identifique prazos com significado para o negócio: uma resposta de terminal antes de o operador tentar novamente, um batch concluído antes da abertura do mercado seguinte ou uma exportação entregue antes do limite do parceiro. Registe as distribuições atuais quando existirem provas e defina limites de destino. Uma promessa vaga de que o sistema novo será mais rápido não sustenta a aceitação.
A arquitetura também altera o plano de transição. Uma substituição única exige paridade total e uma reversão credível antes de mover o tráfego. Uma substituição incremental exige regras de encaminhamento, fluxos de dados de coexistência e prova de que os componentes antigos e novos concordam durante a transição. Nenhuma abordagem é sempre mais barata. A estimativa deve mostrar a maquinaria temporária de que cada abordagem precisa e quando ela pode ser retirada.
Quando os revisores veem a preservação do comportamento e o desenho de destino em linhas separadas, as escolhas tornam-se honestas. Podem simplificar uma fronteira de destino sem fingir que uma regra antiga desapareceu, ou retirar uma regra antiga através de uma decisão explícita do negócio. Esse é o controlo de que um responsável de engenharia precisa antes de aceitar um número fixo.
Um modelo ponderado torna as suposições visíveis
Uma boa estimativa de reescrita de software combina dimensões medidas e mostra como cada uma altera o esforço. Não precisa de uma fórmula universal. Precisa de um modelo que os revisores possam questionar, atualizar e ligar a provas.
Comece com uma tabela de inventário ao nível dos subsistemas. Uma linha por unidade implementável ou capacidade de negócio coerente costuma ser mais informativa do que uma linha por repositório. Use colunas como estas:
| Dimensão | O que registar | Porque muda o trabalho |
|---|---|---|
| Volume de código | Código de produção escrito à mão por linguagem | Define o volume de inspeção e substituição |
| Fluxo de controlo | Rotinas complexas, aninhamento, chamadas não resolvidas | Define a descoberta de caminhos e as fixtures |
| Fronteiras | Contratos, proprietários, substitutos de teste | Define a coordenação e os testes de falhas |
| Dados | Mapeamentos, códigos ocultos, modo de migração | Define a transformação e a reconciliação |
| Superfície de testes | Entradas reproduzíveis e saídas comparáveis | Define a criação de provas e a aceitação |
| Operações | Trabalhos, pontos de reinício, funções, alertas | Define a prontidão para produção |
Atribua confiança ao lado de cada medição. "42 interfaces, 39 inspecionadas, 3 inferidas" é mais útil do que "42 interfaces". Registe a fonte da prova, como análise estática, rasto de produção, análise da configuração, entrevista ou dados de exemplo. Um item inferido deve levar mais contingência do que um observado.
Depois, expresse a estimativa em intervalos por frente de trabalho. Um modelo interno simples poderia ter este aspeto:
replacement = source inventory adjusted for repetition and generated code
behavior proof = consequential paths x fixture cost x evidence gap
integration work = contract implementation + failure proof + owner delay risk
data work = mapping + transformation + rehearsal + reconciliation
operations = deployment + observability + recovery exercises
Não transforme esse esboço em aritmética falsa. Os multiplicadores devem vir do trabalho concluído da própria equipa de entrega e as unidades precisam de definições. O objetivo é mostrar por que razão dois sistemas com tamanho semelhante recebem estimativas diferentes.
Os intervalos devem estreitar quando a prova melhora. Antes do acesso ao código, uma proposta pode ter limites amplos e suposições explícitas. Depois da análise do repositório, da amostragem do tráfego e das entrevistas sobre integrações, o fornecedor deve substituir suposições por contagens. Se o número se mantiver fixo enquanto a prova muda, a estimativa original era provavelmente um objetivo comercial e não um resultado de engenharia.
A CodeHero lê toda a base de código em várias linguagens e usa tráfego de produção gravado num banco de paridade. Assim, a sua estimativa consegue ligar a estrutura do código ao comportamento observável em vez de aplicar a mesma taxa a todas as linhas. Isso não desculpa dados de entrada pouco claros: os responsáveis de engenharia devem pedir para ver o que foi contado, o que o tráfego representa e que fronteiras continuam sem prova.
Como uma estimativa falha num sistema pequeno
Considere uma aplicação de preços de sinistros com 38.000 linhas. Uma proposta baseada em linhas faz com que pareça modesta. O repositório contém um cliente de desktop, uma biblioteca de cálculo, procedimentos SQL e uma exportação noturna. Os testes existentes cobrem a biblioteca de cálculo e a equipa trata inicialmente o resto como infraestrutura comum.
A descoberta encontra quatro factos. O cliente escolhe caminhos de cálculo ativando e desativando campos antes de chamar a biblioteca. As regras de produto vivem em seis tabelas SQL mantidas pelas operações. A exportação noturna só é aceite quando os totais do trailer coincidem com um cálculo independente do parceiro. Recalcular um sinistro histórico depende da versão da tabela de regras que estava ativa na data original do serviço.
Nenhum desses factos acrescenta muitas linhas de código. Cada um aumenta o comportamento que tem de ser capturado. O estado do cliente torna-se um contrato de entrada. As tabelas de regras precisam de fixtures com versões e regras de migração. A lógica do trailer precisa de exemplos do parceiro e testes de rejeição. O recálculo histórico precisa de reconstrução de dados baseada no tempo.
Suponha agora que a suite de testes atual executa 85 por cento da biblioteca de cálculo. O número parece tranquilizador, mas cobre apenas o componente cujas entradas o cliente já transformou. Um plano de paridade tem de capturar a ação do utilizador, o estado do cliente, a versão da regra selecionada, as alterações na base de dados, o resultado do cálculo e o registo de exportação. A superfície de testes útil vai de uma ponta à outra, mesmo que a arquitetura de destino separe bem essas responsabilidades.
A estimativa muda porque a unidade de trabalho passou de linhas substituídas para comportamentos provados. A equipa pode continuar a reescrever apenas 38.000 linhas. Também precisa de identificar caminhos de decisão da interface, extrair o histórico de regras, simular a validação do parceiro e comparar saídas antigas e novas nos casos gravados. Chamar-lhe derrapagem seria desonesto se a proposta original nunca mediu esses itens.
Há uma resposta prática quando a descoberta revela esta forma. Congele o preço fixo até o fornecedor produzir o inventário de fronteiras e o plano de paridade. Não precisa de todos os testes escritos antes da assinatura do contrato, mas precisa de contagens, fontes de prova, exclusões e um método para transformar desconhecidos em decisões. Caso contrário, o contrato transfere no papel um risco impossível de conhecer e deixa ambas as partes a discutir depois.
Peça o pacote de medição antes de assinar
Um responsável de engenharia deve receber a estimativa e as provas por trás dela. Um total bem apresentado sem o pacote de medição impede a revisão técnica e torna quase inevitáveis as discussões posteriores sobre o âmbito.
O pacote deve responder a um conjunto compacto de perguntas:
- Que categorias de código foram contadas, o que foi excluído e podemos executar novamente o inventário?
- Onde estão os caminhos de decisão mais profundos e com maiores consequências, incluindo chamadas dinâmicas não resolvidas?
- Que contratos externos existem, quem é responsável por eles e quais podem ser testados fora da produção?
- Que significados dos dados, migrações e regras de reconciliação continuam por resolver?
- Que entradas podem ser reproduzidas, que saídas podem ser comparadas e como são normalizadas as diferenças aceitáveis?
Peça respostas por subsistema, com etiquetas de confiança e fontes de prova. Uma média para todo o repositório não chega. Uma interface de liquidação impossível de testar pode dominar o risco, enquanto cinquenta módulos comuns fazem a média parecer segura.
As condições comerciais devem seguir as medições. Um âmbito fixo funciona quando as fronteiras e as provas de aceitação são conhecidas. Uma fase de descoberta paga pode fazer sentido quando faltam acesso, proprietários ou rastos de produção, mas deve produzir artefactos reutilizáveis em vez de uma apresentação: inventários, grafos, mapeamentos, amostras e um intervalo atualizado. A contingência deve estar ligada a incógnitas identificadas e diminuir quando o cliente as resolve.
Rejeite estimativas que oferecem precisão sem exclusões. Rejeite também o movimento oposto, quando um fornecedor chama incerto a tudo e pede tempo ilimitado. Uma boa estimativa reduz a incerteza através da inspeção do código, do seguimento do comportamento e dos testes nas fronteiras. Mostra que incógnitas ficam e quem as pode eliminar.
A CodeHero compromete-se a entregar em menos de 30 dias, o que torna obrigatória a medição antecipada do código, comportamento, integrações, dados e operações. Seja qual for o fornecedor considerado, exija que a estimativa nomeie o sistema testável que pretende entregar. Um total de linhas descreve o material no chão. O pacote de medição descreve o edifício que o fornecedor é responsável por concluir.
Perguntas frequentes
Qual é a precisão de uma estimativa baseada em linhas de código?
Só é precisa como medida do volume de código-fonte a inspecionar. O preço pode errar por um fator grande quando uma base pequena tem ramos profundos, regras de dados ocultas, testes fracos ou fronteiras que não podem ser exercitadas fora da produção.
O que deve ser excluído de uma contagem de linhas de código?
Apresente separadamente código gerado, dependências de terceiros, comentários, testes, configuração e código de produção, em vez de os eliminar de um total. As exclusões devem ser documentadas e reproduzíveis porque o código gerado e a configuração operacional ainda afetam partes da reescrita.
A complexidade ciclomática prevê o custo da reescrita?
Nenhuma pontuação de complexidade prevê sozinha o custo. Use a complexidade ciclomática para localizar caminhos independentes e depois inspecione aninhamento, estado mutável, chamadas dinâmicas e consequências para o negócio, de modo a decidir o trabalho de descoberta e as provas de paridade.
Como afetam as integrações externas uma proposta de reescrita?
Cada fronteira acrescenta trabalho de contrato, tratamento de falhas, coordenação, credenciais e prova. Uma troca de ficheiros mal documentada sem endpoint de teste pode custar mais a validar do que várias APIs comuns, por isso a proposta deve separar implementação e testes.
O que é a superfície de testes de um sistema antigo?
A superfície de testes é o conjunto de entradas que pode acionar e de saídas ou efeitos secundários que pode comparar. Inclui pedidos, ficheiros, mudanças na base de dados, mensagens, relatórios, erros e resultados operacionais, não apenas os testes unitários guardados com o código.
O tráfego de produção pode testar uma reescrita?
Sim, o tráfego gravado pode fornecer casos de paridade realistas se a equipa ocultar dados sensíveis, reconstruir o estado necessário e bloquear efeitos perigosos. Não substitui testes direcionados para ramos raros, falhas, limites temporais ou casos ausentes da janela gravada.
Porque encarecem as migrações de dados reescritas pequenas?
O esforço segue o significado e o acoplamento dos dados, não o tamanho da base. Campos sobrecarregados, versões históricas de regras, procedimentos armazenados, registos inválidos e reconciliação rigorosa podem criar muito trabalho de análise e prova mesmo com poucas linhas.
Os scripts operacionais devem entrar no âmbito da reescrita?
Sim. Agendadores, scripts de implementação, regras de acesso, alertas, pontos de reinício e procedimentos do operador determinam se a substituição funciona e recupera. Deixá-los para depois da paridade funcional adia requisitos capazes de alterar a arquitetura.
Que provas devem acompanhar um preço fixo de reescrita?
Peça contagens reproduzíveis, distribuições de complexidade, inventários de fronteiras e dados, um plano de comparação do comportamento, âmbito operacional, exclusões, etiquetas de confiança e incógnitas identificadas. O preço deve ser rastreável até esses artefactos por subsistema.
Quando é razoável pagar a descoberta antes de reescrever?
É razoável quando o fornecedor não tem acesso ao código, rastos de produção, proprietários das integrações ou dados representativos. Deve terminar com artefactos técnicos reutilizáveis e uma estimativa mais estreita, não com uma apresentação que deixa as incógnitas iniciais intactas.