
Olá, pessoal! Neste artigo eu vou comentar algumas técnicas, abordagens e ferramentas que podem ajudar quem se depara com a difícil tarefa que é a manutenção e adição de novas funcionalidades associadas a um código fonte existente.
Antes de começar, queria aproveitar a oportunidade e divulgar o meu blog pessoal e o meu twitter (@pichiliani), onde procuro postar sobre diversos assuntos incluindo programação, banco de dados e outros.
Voltando ao assunto do artigo, imaginem a seguinte situação: um programador recebeu a tarefa de manter um código fonte existente, também chamado de legado, sem conhecer o ele faz, as regras de negócio, o domínio do problema e quais são os requisitos associados a este artefato. Por onde este profissional deve começar? Muitos leitores podem sugerir a abordagem manual de mergulhar de cabeça no código fonte e começar a entender os detalhes de funcionamento do programa. Esta técnica pode funcionar, mas existem alternativas que podem ajudar o profissional tanto no entendimento do código, como nos trabalhos futuros a serem realizados nele.
Neste artigo vou apresentar algumas técnicas, abordagens, ferramentas e outros recursos que podem auxiliar quem recebe de presente um código fonte com muitas linhas de código e precisa aprender o mais rápido possível o que ele faz, para, assim, poder implementar mudanças ou fornecer manutenção.
Para simplificar, vou sugerir o seguinte cenário: um desenvolvedor recebe um script SQL com 6.500 linhas de código escrito na linguagem T-SQL, que ele não conhece. O conteúdo do script está funcionando corretamente e a tarefa é compreender o que ele faz o mais rápido possível para implementar novas funcionalidades e modificar aspectos existentes. Apesar de focar neste exemplo, o que discutirei neste artigo pode ser aplicado para outras linguagens de programação, frameworks, bibliotecas e cenários que envolvam código fonte. Destaco que o conteúdo deste artigo é complementar aos artigos sobre Dez técnicas de otimização de instruções SQL e Dicas de produtividade para DBAs.
1. Use alguma ferramenta de controle de versão
Antes de tocar em código fonte legado, é muito recomendado colocar este artefato de software em algum tipo de ferramenta que faz o controle de versão. Independente da linguagem, plataforma ou recursos utilizados para o desenvolvimento, qualquer alteração deve ser rastreada de maneira clara e simples. Atualmente, existem diversas opções para isso incluindo Git Hub, CSV, Mercurial, Team Foundation e outros. Basta escolher a que melhor se adeque à plataforma de desenvolvimento, projeto ou preferências pessoais.
2. Procure qualquer documentação existente

Ah, a famosa documentação… Em alguns projetos de software é mais fácil achar um trevo de quatro folhas do que algum tipo de documentação, mas mesmo assim deve-se fazer um esforço adicional para descobrir qualquer documentação que ajude a compreender, em um alto nível de abstração, o funcionamento do código fonte legado. Aqui podemos encarar documentação como, documentos em texto, figuras, casos de uso, relatório de erros, e-mails, memorandos, atas de reunião, etc. Do ponto de vista de banco de dados, já escrevi um artigo aqui no iMasters há algum tempo comentando sobre alguns documentos envolvidos com projetos que utilizam banco de dados.
3. Formate o código fonte em algo legível

Quando trabalhamos com código fonte legado, independente da linguagem de programação, é muito comum que este código tenha sido manipulado por mais de uma pessoa ao longo do tempo. E se não há regras bem claras (e reforçadas) para padrões de programação e estilo de código, é bem provável que cada pessoa responsável por alguma alteração do código fonte utilizou suas preferências de formatação. Ou seja, a estrutura visual e estética do código pode estar uma bagunça e importa muito quando se está começando a compreender um código legado.
A sugestão aqui é utilizar alguma ferramenta que automaticamente modifica aspectos visuais do código fonte, como letras maiúsculas ou minúsculas, espaços de indentação, local de definição de variáveis e outros aspectos. Nota-se que tais ferramentas não alteram a funcionalidade do código, pois elas apenas o organizam para que seja mais fácil a sua visualização. No caso do SQL, existe um formatador on-line de instruções muito interessante chamado Instant SQL Online Formater que ajuda bastante a tornar o código SQL visualmente mais fácil de ser compreendido.
4. Obtenha métricas
Se o seu código fonte legado estiver funcionando, uma boa dica é que você obtenha alguma métrica de software sobre ele antes de começar a manipulá-lo. Estas métricas podem ser obtidas de forma automática e lhe ajudam a fornecer estimativas de tempo e esforço necessários quando for preciso informar a um gerente de projeto ou superior o quão feio está a situação e quais recursos (tempo, ferramentas, pessoas) você vai precisar para mexer neste vespeiro.
Uma das ferramentas que recomendo para a geração automática de métricas de software é o PMD. Ele utiliza a técnica de análise estática de código (static code analysis) para varrer um conjunto de arquivos com código fonte em Java e fornece diversas informações relevantes, incluindo possíveis locais de bugs, código morto (variáveis, parâmetros e métodos não utilizados), código sub-optimizado, expressões muito complexas e código duplicado.

Também recomendo o Thinking Craftsman’s Tool Kit, pois ele é uma excelente ferramenta para descobrir trechos de repetição em código fonte de diversas linguagens de programação, algo muito comum em código legado. Alias, aqui vai uma dica pessoal: saber encontrar trechos grandes de código fonte em script legado é muito importante e isso vai economizar um bom tempo quando alguma técnica de refatoração for utilizada.

Se o objetivo é apenas uma análise superficial das linhas de código, há uma ferramenta chamada Universal Code Lines Counter que é muito útil quando se possui uma quantidade grande de código fonte e deseja-se saber o quanto deste código efetivamente é código fonte, linhas em branco ou comentários. Seguindo esta mesma linha, temos também o CLOC e a suíte de ferramentas da empresa Understand.

5. Visualize o seu código fonte de forma diferente
O código fonte de uma linguagem de programação é basicamente um texto com cujo conteúdo segue as regras da linguagem de programação escolhida. Atualmente, existem diversas técnicas de visualização de dados importantes que podem ajudar a compreender o código fonte superficialmente sem a necessidade do entendimento linha a linha. Estas técnicas podem economizar muito tempo quando se precisa entender, em linhas gerais, qual é o conteúdo do arquivo e quais são os elementos manipulados.
Por exemplo, a técnica de nuvem de tags (tag cloud) pode ser útil em um script SQL, pois podemos notar quais as principais tabelas, colunas e objetos estão sendo utilizados, analisando a frequência em que seus nomes aparecem. Também é possível determinar se há muito mais instruções de repetição (for, while, do while, etc) do que estruturas condicionais (if, case, else, etc) ou mesmo quais são os tipos de dados mais utilizados (int, varchar, bool, etc). Dentre as diversas opções para geração de nuvem de tags, recomendo a plataforma de visualização Many Eyes, pois além de tag clouds interativas, também é possível analisar o código fonte através das técnicas Word Tree e Phase Net.

Outra maneira muito interessante de visualizar o código fonte é através de fluxogramas. Dentre as opções disponíveis, recomendo a ferramenta Visustin, pois ela aceita diversas linguagens de programação e permite criar um fluxograma a partir de trechos de código fonte. Este técnica é muito útil especialmente para programadores que preferem informações visuais e facilita a compreensão de códigos fonte que contêm muitas estruturas de laço ou condicionais aninhadas. Especialmente se o programador estiver cansado e apresentar dificuldade para compreender o código fonte com apenas uma olhada parcial.

6. Conheça as dependências do seu código fonte
Dentro de um projeto de software é muito provável que um código fonte apresente algum tempo de dependência, seja ela externa ou não. Esta afirmação é particularmente verdadeira quando se fala em componentização e saber quais são as dependências de pacotes, componentes, web services e outros elementos pode ajudar bastante. Um bom ponto de partida é a criação de diagramas que mostrem as externas, como os produzidos pela ferramenta Creole.

Outra visualização interessante que envolve a dependência de chamada de métodos é apresentada pela ferramenta CodeExplorer, que é um plug-in para o IDE Intellij. Este plug-in encontra toda a cadeia de chamada de métodos (callstack) e permite o rastreamento de chamada de métodos através da análise do código fonte em Java.

Se for possível executar o código fonte, o programador pode pensar em considerar a ferramenta JTracer, que cria visualizações a partir do fluxo de execução de programas em Java. Este recurso é ótimo para aprender como utilizar novas bibliotecas, frameworks e programas com múltiplas threads.

7. Escolha uma IDE com recursos para código legado
Existem muitas IDEs para manipular código fonte de diversas linguagens de programação. A escolha da ferramenta depende de vários fatores, porém quando se analisa o código legado superficialmente, notei que alguns recursos são bem mais úteis do que outros. Isso não quer dizer que devamos abandonar a IDE de nossa preferência, mas nada impede que possamos abrir o mesmo arquivo fonte em mais de uma ferramenta ao mesmo tempo: uma para editar o arquivo, compilar e debugar e outra apenas para visualizar.
Um dos IDEs com recursos interessantes para uma visualização do código fonte é o View Infinity. O interessante desta ferramenta é o uso inovador de zoom para separar o código fonte em camadas de visualização diferentes, de acordo com a funcionalidade. Também é interessante olhar para os diagramas e gráficos gerados automaticamente, de acordo com o nível de detalhe escolhido.

Outro recurso que acredito ser muito interessante é a possibilidade de separar trechos do código fonte e aplicar tags a eles. Para isso, recomendo o recurso de #region do Visual Studio.NET, pois ele é muito prático quando estamos analisando, agrupando e separando o código em partes, para depois analisar estas partes com mais calma.
Por fim, uma das funcionalidades que vem ganhando muito destaque para quem está editando código fonte e que pode fazer uma boa diferença no entendimento de código legado envolve a edição colaborativa. Estas ferramentas permitem que mais de uma pessoa trabalhe com o mesmo código fonte ao mesmo tempo e que cada uma delas possa notar o que o outro está fazendo através de múltiplos cursores e outros recursos de percepção remota. Dentre as aplicações on-line que possuem este recurso destaco o Collabedit, o Etherpad e o Primarypad.com.

8. Gere documentação
Alguns arquivos de código fonte legado podem conter muitos comentários que valem a pena serem analisados separados do código. Para isso, recomenda-se utilizar alguma ferramenta que gere a documentação a partir do código fonte. Há, inclusive, tags específicas quer auxiliam na geração da documentação.
Para quem trabalha com Java, é possível utilizar a ferramenta que gera a documentação no formato Javadoc, fornecidas pela própria plataforma, ou contar com ferramentas tais como o Doxygen.
Outra documentação interessante que pode ser gerada a partir do código fonte envolve a engenharia reversa, ou seja, a partir do código fonte criar diagramas. O caso clássico envolve a análise de pacotes Java (arquivos jar) e geração do diagrama de classes. Uma ferramenta que faz isso muito bem é o ArgoUML, porém existem outras. Já para diagramas de sequência, existe o Heatlamp, que analise o código fonte e diagramas de sequência que facilitam a compreensão de como as classes interagem entre si, auxiliando muito quem precisa trabalhar com código legado.

Também vale a pena destacar que não é preciso ferramentas específicas para gerar diagramas da UML que ajudam no código fonte. O site yUML é um exemplode que para gerar diagramas que auxiliem o trabalho de outros, basta um pouco de boa vontade. A propósito, que tal incluir técnicas de MDD (Model-Drive Development) para relacionar diretamente o código fonte com os modelos?

9. Refatoração, testes e integração contínua
Já que vai ser necessário compreender como o código legado funciona, que tal aproveitar esta oportunidade e realizar refatorações, criar testes e implementar alguma ferramenta de integração contínua? Estas práticas vão ser muito úteis em ocasiões futuras onde será preciso manipular novamente este código fonte e que serão de grande ajuda para o projeto de software como um todo. Independente da tecnologia, plataforma, linguagem de programação ou recurso utilizado, a refatoração, os testes e a integração contínua sempre podem ser implementados.
10. Ferramenta de comparação
Se você pretende alterar um código fonte existente complexo e que já carrega diversas alterações no seu histórico, eu recomendo fortemente que faça uso de alguma ferramenta de comparação entre diferentes versões. O motivo desta recomendação éque provavelmente você vai querer comparar como o código estava antes e depois de alguma alteração. Esta comparação faz muito sentido, principalmente quando a menor das mudanças gera um efeito catastrófico e insere bugs em sistemas, programas ou algoritmos que já funcionam há um bom tempo. E na hora da correria, nada mais prático de que saber exatamente onde, quando e por que uma modificação foi feita no código fonte.
Novamente, existem diversas ferramentas que podem ser úteis neste processo. Os sistemas de controle de versões já fornecem algum recurso para esta comparação, porém recomendo a ferramenta WinMerge, pois além dela comparar os arquivos modificados, ainda possui recursos para aceitar, ignorar ou mesclar as alterações. Ela possui recursos adicionais como pesquisas e comparações de diretórios inteiros.

Um grande abraço, pessoal, e até a próxima.



