Eu já vi o livro Trabalhando efetivamente com o código herdado algumas vezes. Quais são os pontos principais deste livro?
Há muito mais para lidar com código legado do que adicionar testes de unidade / integração e refatorar?
Eu já vi o livro Trabalhando efetivamente com o código herdado algumas vezes. Quais são os pontos principais deste livro?
Há muito mais para lidar com código legado do que adicionar testes de unidade / integração e refatorar?
Respostas:
O principal problema do código legado é que ele não possui testes. Então você precisa adicionar alguns (e mais ...).
Isso por si só exigiria muito trabalho, como observou @mattnz. Mas o problema especial do código legado é que ele nunca foi projetado para ser testável . Normalmente, é uma enorme bagunça complicada de código de espaguete, em que é muito difícil ou absolutamente impossível isolar pequenas peças para serem testadas em unidade. Portanto, antes do teste de unidade, é necessário refatorar o código para torná-lo mais testável.
No entanto, para refatorar com segurança, você deve ter testes de unidade para verificar se não quebrou nada com suas alterações ... Esta é a captura 22 do código legado.
O livro ensina como interromper essa captura, fazendo as alterações mínimas e mais seguras no código, apenas para permitir os primeiros testes de unidade. Elas não são destinadas a tornar o design mais agradável - apenas para permitir testes de unidade. De fato, às vezes eles tornam o design mais feio ou mais complexo. No entanto, eles permitem que você escreva testes - e depois que você tiver testes de unidade, você estará livre para melhorar o design.
Existem muitos truques para tornar o código testável - alguns são óbvios, outros nem um pouco. Existem métodos que eu nunca teria pensado em mim mesmo sem ler o livro. Mas o mais importante é que Feathers explica o que torna precisamente uma unidade de código testável. Você precisa cortar dependências e introduzir barreiras no seu código, mas por dois motivos distintos:
Cortar dependências com segurança pode ser complicado. A introdução de interfaces, zombarias e injeção de dependência é um objetivo limpo e agradável, mas não necessariamente seguro de fazer neste momento. Às vezes, temos que recorrer à subclasse da classe em teste para substituir algum método que normalmente, por exemplo, iniciaria uma solicitação direta a um banco de dados. Outras vezes, podemos até precisar substituir uma classe / jar de dependência por uma classe falsa no ambiente de teste ...
Para mim, o conceito mais importante trazido por Feathers é costuras . Uma costura é um local no código onde você pode alterar o comportamento do seu programa sem modificar o próprio código . A criação de costuras em seu código permite separar o trecho de código em teste, mas também permite detectar o comportamento do código em teste, mesmo quando é difícil ou impossível fazê-lo diretamente (por exemplo, porque a chamada faz alterações em outro objeto ou subsistema , cujo estado não é possível consultar diretamente de dentro do método de teste).
Esse conhecimento permite que você observe as sementes da testabilidade no monte de códigos mais desagradável e encontre as alterações mínimas, menos perturbadoras e mais seguras para chegar lá. Em outras palavras, para evitar fazer refatorações "óbvias" que correm o risco de violar o código sem você perceber - porque você ainda não tem os testes de unidade para detectá-lo.
Maneiras rápidas de obter os pontos principais de Trabalhar efetivamente com o código herdado
Eu trabalho em uma base de código de milhões de linhas de código, algumas que datam dos anos 80. É apenas software, por isso é apenas uma questão de escrever alguns testes de unidade, para que você possa refatorá-lo e torná-lo muito melhor.
A palavra-chave aqui é apenas: é uma palavra de quatro letras que não pertence ao vocabulário de nenhum programador, muito menos a alguém que está trabalhando em sistemas legados.
Quanto tempo você acha necessário para escrever um teste de unidade, para testar uma hora no esforço de desenvolvimento? Para fins de discussão, digamos mais uma hora.
Quanto tempo é investido nesse sistema legado de 20 milhões de anos? Digamos, 20 desenvolvedores por 20 anos, 2000 horas / ano (eles trabalharam bastante). Vamos agora escolher um número - você tem novos computadores e novas ferramentas e é muito mais esperto do que os caras que escreveram esse pedaço de $% ^^ em primeiro lugar - digamos que você vale 10 deles. Você tem 40 anos homem, bem, você tem ...?
Portanto, a resposta para sua pergunta é que há muito mais. Por exemplo, essa rotina com 1000 linhas (tenho algumas com mais de 5000), é excessivamente complexa e é um pedaço de espaguete. Apenas (mais uma palavra de quatro letras) levaria alguns dias para redimensioná-lo em algumas rotinas de 100 linhas e mais alguns 20 auxiliares de linha, certo? ERRADO. Oculto nessas 1000 linhas, há 100 correções de bugs, cada uma delas um requisito de usuário não documentado ou um caso obscuro. São 1000 linhas porque a rotina original de 100 linhas não fez o trabalho.
Você precisa trabalhar com a mentalidade " se não estiver quebrada, não conserte ". Quando está quebrado, você precisa ter muito cuidado ao corrigi-lo - à medida que melhora, para não mudar acidentalmente outra coisa. Observe que "interrompido" pode incluir código que não pode ser mantido, mas está funcionando corretamente, que depende do sistema e de seu uso. Pergunte "o que acontece se eu estragar tudo e piorar", porque um dia você fará isso e terá que dizer ao chefe dos chefes por que escolheu fazer isso.
Esses sistemas sempre podem ser aprimorados. Você terá um orçamento para trabalhar, uma linha do tempo, o que for. Se não, vá e faça um. Pare de melhorar quando o dinheiro / tempo acabar. Adicione um recurso, reserve um tempo para torná-lo um pouco melhor. Corrija um bug - novamente, gaste um pouco de tempo extra e melhore. Nunca entregue pior do que era quando você começou.
Existem dois pontos principais a serem retirados do livro.
Como outros respondentes apontaram, tentar atualizar preventivamente seu código legado existente é uma tarefa fácil . Em vez disso, sempre que você precisar fazer uma alteração no código legado (para um novo recurso ou uma correção de bug), reserve um tempo para remover seu status legado.