“Tenho tido noites sem dormir tentando adicionar recursos no código que adquirimos de outra empresa. Estou lidando com a forma mais pura do Legacy Code”

“Estou tendo muita dificuldade para lidar com códigos emaranhados e não estruturados com os quais tenho que trabalhar, mas não entendo nem um pouco. Legacy Code !”

Legacy Code é um termo que provavelmente tem muitas definições diferentes como -código adquirido de outra pessoa, código escrito por outra pessoa, código que é difícil de entender ou código escrito em tecnologias ultrapassadas. Seja qual for a definição, a maioria de nós acredita que Legacy Code é Scary.

Question> Como você definiria código legado?

Definindo Legacy Code

Michael Feathers em seu livro “Working Effectively with Legacy Code” define código legado como, código sem testes.

Código sem testes é um código ruim. Não importa quão bem escrito está; quão bem estruturado está; quão bem encapsulado está.Sem testes não há como dizer se nosso código está ficando melhor ou pior.

Bem, uma versão ligeiramente modificada desta definição é “código sem testes unitários é chamado de código legado”. É sempre melhor ter testes o mais próximo possível do código (testes unitários > testes de integração > testes UI). Portanto, não seria injusto chamar um código sem testes de unidade de um código legado.

Trabalhar com código legado

Question> Que abordagem você adotaria se fizesse uma mudança no código legado?

A maioria de nós poderia dizer: “Eu farei a mudança e a chamarei de um dia, por que se preocupar em melhorar o código”. A razão por trás deste processo de pensamento poderia ser –

  • Não tenho tempo suficiente para refactorizar o código, Eu preferia fazer uma mudança e completar minha história
  • Por que arriscar mudar a estrutura do código que está em produção há muito tempo
  • Qual é o benefício geral de refatorar o código legado

>

Michael Feathers chama esse estilo de fazer uma mudança como Editar e Rezar. Você planeja e faz suas mudanças e quando terminar, você reza e reza mais para fazer as mudanças corretamente.

Com este estilo, só se pode contribuir para aumentar o código legado.

>

>

Existe um estilo diferente de fazer mudanças que é Cover and Modify. Construa uma Rede de Segurança, faça alterações no sistema, deixe que a Rede de Segurança forneça feedback e trabalhe nesses feedbacks.

É possível assumir com segurança que Cover and Modify é uma maneira de lidar com código legado.

Question> Mas, você deve até mesmo gastar tempo escrevendo testes em código legado ou mesmo pensando em refactoring a legacy code?

>

Deveria você até mesmo gastar tempo pensando em refactoring Legacy Code ?

A Regra do Escoteiro

>

A ideia por trás da Regra do Escoteiro, como disse o tio Bob, é bastante simples: Deixe o código mais limpo do que você o encontrou! Sempre que você tocar em um código antigo, você deve limpá-lo corretamente. Não aplique apenas uma solução de atalho que torne o código mais difícil de entender, mas trate-o com cuidado. Não basta escrever bem o código, o código tem que ser mantido limpo ao longo do tempo.

Recebemos uma mensagem muito forte quando a regra do Boy Scout é aplicada ao código antigo “deixe um traço de compreensão para os outros seguirem”, o que significa que vamos refatorar o código para torná-lo mais compreensível. E para refactor, vamos construir Safety Net em torno dele.

Agora entendemos que não podemos tomar atalhos a única opção que nos resta é escrever alguns testes, refactor code e prosseguir com o desenvolvimento. Perguntas>

  • Que testes devemos escrever?
  • Quanto devemos refactor?

Que testes devemos escrever

Em quase todos os sistemas legados, o que o sistema faz é mais importante do que o que é suposto fazer.

Testes de Caracterização, os testes que precisamos quando queremos preservar o comportamento são chamados de testes de caracterização. Um teste de caracterização é um teste que caracteriza o comportamento real de um pedaço de código. Não há “Bem, ele deve fazer isso” ou “Eu acho que ele faz isso”. Os testes documentam o comportamento atual real do sistema.

Teste de Caracterização de Escrita

Um Teste de Caracterização por definição documenta o comportamento atual real do sistema exatamente da mesma forma que ele está rodando no ambiente de Produção.

Vamos escrever um Teste de Caracterização para um objeto de um cliente que gera declaração de texto para alguns filmes alugados por um cliente.

import static com.code.legacy.movie.MovieType.CHILDREN;
import static org.junit.Assert.assertEquals;public void shouldGenerateTextStatement(){ Customer john = new Customer("John");
Movie childrenMovie = new Movie("Toy Story", CHILDREN);
int daysRented = 3;
Rental rental = new Rental(childrenMovie, daysRented); john.addRental(rental); String statement = john.generateTextStatement();
assertEquals("", statement);
}

Este teste tenta entender (ou caracterizar) a geração de “Declaração de Texto” para um cliente dado um filme infantil alugado por 3 dias. Como não entendemos o sistema (pelo menos a partir de agora), esperamos que a declaração esteja em branco ou contenha qualquer valor falso.

Vamos executar o teste e deixá-lo falhar. Quando o fizer, descobrimos o que o código realmente faz sob essa condição.

java.lang.AssertionError: 
Expected :""
Actual :Rental Record for John, Total amount owed = 12.5. You earned 4 frequent renter points.

Agora, que sabemos o comportamento do código, podemos prosseguir e mudar o teste.

import static com.code.legacy.movie.MovieType.CHILDREN;
import static org.junit.Assert.assertEquals;public void shouldGenerateTextStatement(){
String expectedStatement = "Rental Record for John, Total amount owed = 12.5. You earned 4 frequent renter points"; Customer john = new Customer("John");
Movie childrenMovie = new Movie("Toy Story", CHILDREN);
int daysRented = 3;
Rental rental = new Rental(childrenMovie, daysRented);
john.addRental(rental); Sting statement = john.generateTextStatement();
assertEquals(expectedStatement, statement);
}

Espera, acabamos de copiar a saída gerada pelo código e colocada em nosso teste. Sim, foi exactamente isso que fizemos.

Não estamos a tentar encontrar bugs neste momento. Estamos tentando colocar um mecanismo para encontrar bugs mais tarde, bugs que aparecem como diferenças em relação ao comportamento atual do sistema. Quando adotamos esta perspectiva, nossa visão dos testes é diferente: eles não têm nenhuma autoridade moral; eles apenas se sentam lá documentando o que o sistema realmente faz. Nesta fase, é muito importante ter esse conhecimento do que o sistema realmente faz em algum lugar.

Question> Qual é o número total de testes que escrevemos para caracterizar um sistema?

Answer> É infinito. Poderíamos dedicar uma boa parte das nossas vidas a escrever caso após caso para qualquer classe num código legado.

Question> Quando é que paramos então? Existe alguma forma de saber quais casos são mais importantes que outros?

Resposta> Olha o código que estamos a caracterizar. O próprio código pode nos dar idéias sobre o que ele faz, e se tivermos perguntas, os testes são uma forma ideal de fazê-las. Nesse momento, escreva um teste ou testes que cubram uma parte suficientemente boa do código.

Question> Isso cobre tudo no código?

Answer> Pode não cobrir. Mas depois damos o próximo passo. Pensamos nas mudanças que queremos fazer no código e tentamos descobrir se os testes que temos vão sentir algum problema que possamos causar. Se não o fizerem, adicionamos mais testes até nos sentirmos confiantes de que o farão.

How Much To Refactor?

Há tanto para refactor no código legado e não podemos refactor tudo. Para responder isso, precisamos voltar a entender nosso propósito de refatorar o código legado.

Queremos refatorar o código legado para deixá-lo mais limpo do que era quando chegou até nós e torná-lo compreensível para os outros.

Dito isto, queremos tornar o sistema melhor mantendo o foco na tarefa. Não queremos enlouquecer com a refatoração tentando reescrever o sistema inteiro em poucos dias. O que queremos fazer é “refactor o código que vem na nossa maneira de implementar qualquer nova mudança”. Vamos tentar entender isso melhor com um exemplo no próximo artigo.

Conclusion

Articles

Deixe uma resposta

O seu endereço de email não será publicado.