Tradução: Refatorando seu código legado - Parte 1: No início houve…
Este artigo é uma tradução do artigo Refactoring your legacy code - Part One: In the beginning there was…, caso você encontre erros de português, concordância, tem algum comentário ou agradecimento, FAÇA! É como um amigo meu sempre fala, se você ver alguma coisa errada, conserte!
Lars Jankowfsky é desenvolvedor PHP e participou da International PHP Conference 2008. Ele possui o Frontalaufpral onde ele fala sobre PHP, Agile Development e outros assuntos.
Deixa de papo e vamos a tradução!
Refatorando seu código legado - Parte Um: No início houve…
Como prometido, Tomas e eu iremos procurar mostrar uma visão sobre o que você precisa considerar quando você planejar refatorar suas velhas (legadas) aplicações. Não será um guia detalhado nem muito ordenado. Será mais ou menos nossas experiências e pensamentos nos últimos anos.
Se você precisa de uma introdução mais detalhada (incluindo a nível de código) você deve participar de nosso workshop na Internation PHP Conference 2008. Eu irei ministrar o workshop juntamente com dois dos melhores programadores PHP (Johann Peter Hartmann e Thorsten Rinne), você pode esperar muito mais detalhes.
Com certeza eu irei publicar a apresentação após o IPC - mas não antes ;)
Agora - Refatorando, hmm… Refatorar é, por definição, o meio de modificar (limpando) sem alterar o comportamento. Mas como você pode ter certeza que não está mudando o comportamento se você não está fazendo testes? Isto significa - você só pode refatorar um código se ele possui testes. E é aqui que começa o problema - onde está os testes?
E lá vamos nós. Vamos assumir que você possui um grande projeto - que cresceu durante anos. E agora você está na sorte que seu chefe concorda com você sobre a necessidade dos testes. Mas como iniciar? O time não possui experiência escrevendo testes. Pior ainda, nem sabem o que é Test Driven Development.
Você precisará investir um tempo no time para que eles aprendam como escrever testes. E você experimentará que conhecer e compreender são duas coisas diferentes. Na minha opinião, somente uma coisa pode ser comparada. A diferença entre programação procedural e orientada a objetos. Estranho exemplo? Não.
Deixe-me explicar. É muito fácil pegar um livro e aprender um pouco sobre classes, objetos, etc. Mas somente depois de você usar por um tempo é que você entenderá profundamente o conceito de OOP e buscar o bom senso. O mesmo é para o TDD - escrever testes é mais ou menos questão de minutos. Ou digamos horas se for o seu primeiro teste. Mas entender por quê os testes são importantes e como usá-los. Isto precisa de tempo. E você terá que investir esse tempo.
Depois de eu ter empurrado o time dentro desta direção ( e ei! - isto não foi tão fácil, como muitos desenvolvedores tendem a ser mais conservadores), eles fizeram os testes - simplesmente por quê o chefe disse isso. Mas somente poucas semanas depois, um desenvolvedor disse-me “Ei! Testes são legais! Eu encontrei um bug, eu nunca teria encontrado antes”. Este é o ponto que você precisa para o seu time.
Um pouco mais de teoria. Mas o que dizer dos testes? Por onde começar? Essa resposta é fácil. Você precisa começar com o mais sórdido, mais sujo, e maior arquivo que você pode achar no seu projeto. Eu sei, Eu sei. Eles querem começar com os arquivos mais fáceis, onde os testes são feitos rapidamente e você ver algum progresso. Os desenvolvedores realmente terão medo deste arquivo. Mas o que vai acontecer se você iniciar pelos fáceis? Simples - você verá algum progresso e terá a sensação que as coisas estão tudo bem. Seu time não entenderá os testes completamente - e eles deixam as partes mais sórdidas do código para o final. Você tem que ter forças para resolver os demônios logo no começo. Isso vai demorar um pouco. Mas então você pode ter certeza que o restante vai ser um bom e delicioso pedaço de bolo. De outro modo, você irá mover o parte do risco para o fim do período de refatoração - e isto não é uma boa idéia.
Você poderia pensar “Esse cara é louco, onde está o problema em escrever testes…?” Ei! Nós estamos falando de velho código crescido ( == espaguete ). Este código é massivamente interconectado. Variáveis globais, classes mistas, selvagens chamadas entre módulos e objetos, etc. É muito difícil escrever testes para isto.
Na verdade, enquanto estiver escrevendo testes você notará que precisa refatorar o código. Você simplesmente tem que refatorar. Pois de outra forma você não pode escrever os testes. Ou - vamos ser honesto - você pode. Se você escrever mocks e stubs que é o triplo do tamanho do seu código. Isto é exatamente o que desenvolvedores sem experiência com TDD irão fazer. Se você ver isso - chutem eles! E em seguida novamente, por que a sensação é muito boa ;).
Cada teste leva ao refatoramento. Como o nó górdio (Vejam no wikipedia) você começará a puxar o worm, e irá puxar, puxar e puxar. E após algum tempo a refatoração estará pronta e o primeiro teste pode ser escrito. Ok, só estava brincando. Mas há alguma verdade nesta afirmação. Você precisa refatorar o código primeiro - então escrever o teste. Sem grandes stubs.
E isto será trabalhoso - especialmente no início, onde tudo está interconectado. E algumas dependencias precisam ser abordadas e resolvidas. Primeiro. Separe o modelo da visão. Na visão, deixe sem lógica - somente I/O. E então teste o modelo. Algumas pessoas até mesmo testam as visões com testes unitários. Eu não. Eu prefiro testar o modelo, com pequenas visões sem lógica e deixar o resto para os testes com selenium.
O sórdido. Leva tempo. Muito trabalho. Mas acredite em mim. Não há outra forma.
Durante a leitura, você pode ficar com a idéia de que você vai fugir com os testes de aceitação. (selenium). Você acha que isso é um bom negócio? A idéia é sensacional. Se você escrever testes do selenium para toda a aplicação - então refatorar - e você não quebrar nenhum teste, você pode ter certeza que você não alterou qualquer funcionalidade. Boa ideia? Não vai funcionar. Desculpe
Lembre-se. Eu estou falando de uma grande aplicação que cresceu. Ela terá toneladas de funcionalidades. Isto significa centenas ou milhares de testes. E estes testes podem durar muito. Eu sei disso. Eu fui até esta estrada - e ela é uma estrada de mão uníca. Nós terminamos com um teste completo rodando por 10 horas. Isso não é desenvolvimento guiado a testes. Para fazer isso que você precisa instantaneamente - instantaneamente - de feedback. Ninguém pode trabalhar assim.
Contínua na parte dois.
Essa foi a primeira parte do artigo. Mais uma vez, espero que vocês gostem. Qualquer dúvida entre em contato! Não deixe de me passar seu feedback.


