Cairo’sBlog

Tradução: Refatorando seu código legado – Parte 1: No início houve…

por Cairo Noleto no dia 17/11/2008, em PHP, TDD, Traduções

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.

:, , , , , , , , ,

3 Comentários para este artigo

  • jaguarnet7

    Muito bom mesmo, estou passando por este problema no trabalho e também começei pelos códigos mais bizarros.

  • jaguarnet7

    te adicionei no gtalk, ok?

  • JoaoJose

    Olá Caio,
    Muito bom esse texto, estamos passando por um problema deste aqui na empresa, pegamos um código legado de um produto de cliente. O problema é que, além de legado, é mal feito =P. Estamos nos matando para refatorar TUDO e esta estratégia explicada pelo Lars é realmente a melhor opção.
    Eu acrescentaria um porém somente. Em uma parte ele recomenda escolher a Classe mais cabeluda para começar. Eu vou além e recomendaria a não escolher uma classe, uma funcionalidade ou uma tela pela sua complexidade, mas sim de acordo com a priorização do cliente, de acordo com que o cliente necessita.

    Mas parabéns pela tradução!

Deixe um comentário

Procurando por alguma coisa?

Não achou o que você está procurando? Deixe um comentário no artigo ou entre em contato