Anda di halaman 1dari 35

CENTRO UNIVERSITRIO CESMAC

CURSO DE PS-GRADUAO LATO SENSU


ENGENHARIA DE SOFTWARE

MELHORANDO A QUALIDADE DO CDIGO COM A TCNICA DE REFATORAO:


estudo de caso em um sistema legado Java

Anderson Lemos Camelo

Macei/AL 2013

Anderson Lemos Camelo

MELHORANDO A QUALIDADE DO CDIGO COM A TCNICA DE REFATORAO:


estudo de caso em um sistema legado Java

Macei/AL 2013

Anderson Lemos Camelo

MELHORANDO A QUALIDADE DO CDIGO COM A TCNICA DE REFATORAO:


estudo de caso em um sistema legado Java

Artigo apresentado ao Centro Universitrio Cesmac como parte dos requisitos para a obteno do ttulo de Especialista em Engenharia de Software, sob a orientao do Prof. Me. Adilson Jorge dos Santos.

Macei/AL 2013

Anderson Lemos Camelo

MELHORANDO A QUALIDADE DO CDIGO COM A TCNICA DE REFATORAO:


estudo de caso em um sistema legado Java

Aprovado em 30 de setembro de 2013

__________________________________________ Prof. Me. Adilson Jorge dos Santos - Orientador -

Macei/AL 2013

AGRADECIMENTOS

Agradeo, primeiramente, a Deus por sempre se colocar como uma ponte para que eu pudesse transpor as guas agitadas do caminho pelo qual trilhei. Agradeo a minha famlia pelo amor e cumplicidade durante todos os momentos de minha vida. Agradeo ao professor Adilson Santos, meu orientador, por incentivar o desenvolvimento do tema escolhido e colaborar com a concluso deste trabalho. Por ltimo, mas no menos importante, agradeo a todas as pessoas que duvidaram da minha capacidade e colocaram meu talento a prova.

Tudo que est no plano da realidade j foi sonho um dia.

Leonardo da Vinci

SUMRIO 1 INTRODUO ........................................................................................... 2 FUNDAMENTAO TERICA ............................................................... 2.1 REFATORAO ........................................................................................ 2.2 CDIGO LIMPO ......................................................................................... 2.3 ODORES DE CDIGO ............................................................................... 2.3.1 CDIGO DUPLICADO .............................................................................. 2.3.2 MTODO LONGO ...................................................................................... 2.3.3 CLASSE GRANDE ..................................................................................... 2.3.4 LISTA DE PARAMETROS LONGA ......................................................... 2.3.5 INVEJA DE DADOS ................................................................................... 2.3.6 COMENTRIOS ......................................................................................... 2.3.7 PROPSITO OBSCURO ............................................................................ 2.4 PROJETO SIMPLES ................................................................................... 2.5 MTRICAS DE CDIGO FONTE ............................................................. 3 METODOLOGIA ........................................................................................ 4 RESULTADOS E DISCUSSO ................................................................. 4.1 ARQUITETURA DO SISTEMA REVERSI ............................................... 4.2 REFATORAO DO SISTEMA REVERSI .............................................. 4.2.1 PORQUE REFATORAR ............................................................................. 4.2.2 O PRIMEIRO PASSO DA REFATORAO ............................................ 4.2.3 O PROCESSO DE REFATORAO ......................................................... 4.2.4 QUANDO PARAR DE REFATORAR ....................................................... 4.3 MTRICAS DO SISTEMA REVERSI ....................................................... 5 CONCLUSO ............................................................................................. REFERNCIAS ........................................................................................................ 1 3 3 4 5 5 6 6 7 7 9 9 11 12 13 14 14 15 15 16 18 23 24 26 26

LISTA DE ILUSTRAES Figura 1 - Exemplo de refatorao de uma lista de parmetros longa ....................... Figura 2 - Exemplo de refatorao de um cdigo acidente de trem ....................... Figura 3 - Exemplo de inveja de dados que no viola a Lei de Demeter .................. Figura 4 - Exemplo de cdigo com propsito obscuro .............................................. Figura 5 - Exemplo de cdigo legvel ........................................................................ Figura 6 - Diagrama de pacotes do Reversi ............................................................... Figura 7 - Particionamento de equivalncia para o Reversi ....................................... Figura 8 - Conjunto de testes automticos do Reversi ............................................... Figura 9 - Mtodo buscaJogadaComputador com vrios odores ............................. Figura 10 - Refatorao do antigo mtodo buscaJogadaComputador ...................... Figura 11 - Mtodo de fbrica obterComputador ...................................................... Figura 12 - Inveja de dados do objeto objControle ................................................... Figura 13 - Responsabilidade reposicionada na classe ControladorDoJogo ............ Figura 14 - Cdigo Acidente de trem ao chamar mtodo getMatPedrasTabuleiro Figura 15 - Refatorao do Acidente de Trem do mtodo getMatPedrasTabuleiro . Figura 16 - Muitas linhas de cdigo no mtodo executaJogada ............................... Figura 17 - Refatorao do mtodo executaJogada .................................................. Figura 18 - Mtricas do projeto Reversi .................................................................... 7 8 9 10 11 15 16 17 19 19 20 20 21 21 22 23 23 25

MELHORANDO A QUALIDADE DO CDIGO COM A TCNICA DE REFATORAO: ESTUDO DE CASO EM UM SISTEMA LEGADO JAVA

Anderson Lemos Camelo


Adilson Jorge dos Santos (Orientador)

RESUMO: Este artigo mostra como a tcnica de refatorao pode ser empregada para melhorar a
qualidade de cdigo de sistema legado desenvolvido em Java. Sero mostrados todos os passos da metodologia necessrios para aplicao da refatorao com segurana. Tambm ser feita uma explorao do sistema legado com o intuito de identificar os principais trechos de cdigo ruim e a melhor estratgia para transform-lo em um cdigo limpo. Ao fim da discusso, sero levantados vrios dados estatsticos do sistema legado, antes e depois da refatorao, para mensurar os ganhos de qualidade de cdigo advindos do uso desta tcnica.

PALAVRAS-CHAVES: Refatorao; Cdigo Legado; Linguagem de Programao Java; Cdigo


Limpo; Testes Automatizados.

ABSTRACT: This article aims to show how the refactoring technique can be used to improve the
quality of a legacy code in a system developed in Java. We will show all the methodology steps needed to safely implement the refactoring. Also there will be an exploration of the legacy system in order to identify key pieces of bad code and the best strategy to turn them into clean code. At the end of the discussion, we will gather statistical data from the legacy system, before and after refactoring, to measure the improvement in code quality from the use of this technique.

KEYWORDS: Refactoring; Legacy Code; Java Programming Language; Clean Code; Automated
Testing.

1 INTRODUO Quando a aplicao da tecnologia de objetos, e particularmente linguagem de programao Java, se tornou corriqueira, um novo problema surgiu para a comunidade de software. Um nmero significativo de programas pobremente projetados, criados por desenvolvedores menos experientes e que faziam uso de metodologias consideradas
1

antiquadas, resultavam em aplicaes ineficientes e difceis de manter e estender. Os profissionais de desenvolvimento de sistemas acabaram descobrindo como difcil trabalhar com aplicaes no-ideais herdadas ou legadas (FOWLER et al., 2004). Segundo Feathers (2004), o conceito de sistemas de software legados no se restringe apenas aos sistemas que possuem muito tempo de vida, continuam em produo e se mantm em uso, mas principalmente aos sistemas desenvolvidos recentemente e que apresentam problemas de qualidade que podem impedir sua evoluo ou at gerar erros graves aps uma simples manuteno. Normalmente estes sistemas no podem ser substitudos por diversas razes, o que os tornam caros quanto manuteno e trazem muitos riscos no momento de sua evoluo. Devido a estes problemas torna-se necessrio melhorar a qualidade desses sistemas legados podendo ser uma forma interessante de mant-los ativos, tornando-os mais uma vez produtivos e permitindo que melhorias e evolues sejam efetuadas com menos riscos. Consequentemente gerado uma maior confiabilidade e segurana a cada evoluo que se faa necessria. O incremento de novas funcionalidades nos sistemas legados com maior qualidade permite que a empresa tenha vantagens competitivas sem grandes investimentos de novos desenvolvimentos, gerando lucros, permitindo tambm a integrao com novos sistemas (SARTORELLI, 2007). Logo, para melhorar a integridade estrutural e o desempenho destes sistemas necessrio recorrer a tcnica de refatorao. A refatorao foi inicialmente concebida nos crculos de Smalltalk, mas no demorou muito a encontrar o seu caminho em outras linguagens de programao. Devido ao fato de refatorao ser essencial ao desenvolvimento de frameworks, o termo vem tona rapidamente quando desenvolvedores de frameworks falam sobre seu trabalho. Ele surge quando eles refinam suas hierarquias de classes e quando se empolgam com o nmero de linhas de cdigo que conseguiram apagar. Desenvolvedores de frameworks sabem que um framework no estar pronto na primeira tentativa - ele deve evoluir medida em que eles ganham experincia. Eles tambm sabem que o cdigo ser lido e modificado mais frequentemente do que ser escrito. A chave para manter o cdigo legvel e modificvel refatorar - para frameworks, em particular, ou para qualquer outro software, de maneira geral (FOWLER et al., 2004).
2

No entanto, o processo de refatorar requer alteraes no cdigo em funcionamento que podem introduzir falhas sutis. A refatorao, se no for feita apropriadamente, pode atrasar o projeto em dias, ou at mesmo semanas. E a refatorao se torna mais arriscada ainda quando praticada informalmente e sem seguir nenhuma metodologia aceita. O programador comea a alterar o cdigo. Logo descobre novas oportunidades de mudanas, e altera ainda mais o cdigo. Quanto mais ele trabalha, mais coisas aparecem e mais alteraes so feitas (FOWLER et al., 2004). No final,o programador no consegue mensurar o impacto das mudanas realizadas no funcionamento do sistema. Para evitar este cenrio de incerteza, a refatorao deve ser feita sistematicamente. O objetivo deste trabalho apresentar a tcnica de refatorao sob uma perspectiva simples e prtica, visando melhorar a qualidade de cdigo de um sistema legado de forma evolutiva e garantindo segurana durante o processo de manuteno. Ser mostrado como aplicar os principais passos da metodologia e as melhores estratgias para transformar um cdigo ruim em um cdigo bom, utilizando como estudo de caso o sistema legado Reversi, desenvolvido na linguagem Java.

2 FUNDAMENTAO TERICA Nesta seo ser apresentada a fundamentao terica levantada sobre os principais conceitos necessrios para o estudo deste trabalho. Ser abordada uma breve explanao sobre refatorao, cdigo limpo, odores de cdigo, projeto simples e mtricas de cdigo fonte. 2.1 REFATORAO Refatorao o processo de alterao de um sistema de software de modo que o comportamento externo do cdigo no mude, mas que sua estrutura interna seja melhorada. uma maneira disciplinada de aperfeioar o cdigo que minimiza a chance de introduo de falhas. Em essncia, quando se usa refatorao, est se melhorando o projeto do cdigo aps este ter sido escrito (FOWLER et al., 2004). O uso da tcnica de refatorao aprimora o design de um software e evita a deteriorao to comum durante o ciclo de vida de um cdigo. Esta deteriorao
3

geralmente causada por mudanas com objetivos de curto prazo ou por alteraes realizadas sem a clara compreenso da concepo do sistema (WIKIPDIA, 2013a). Com a refatorao, descobre-se que o ponto de equilbrio do trabalho muda. Descobre-se que o projeto, em vez de acontecer todo no inicio, ocorre continuamente durante o desenvolvimento. Aprende-se, com a construo do sistema, a como melhorar o projeto. A interao resultante leva a um programa que permanece bom medida em que o desenvolvimento continua (FOWLER et al., 2004). Segundo Fowler et al. (2004), desejado que os programas que sejam fceis de ler, que tenham toda sua lgica especificada em um e apenas um lugar, que no permitam que as alteraes arrisquem o comportamento preexistente e que permitam que lgica condicional seja expressa da forma mais simples possvel. Logo, refatorar processo de pegar um programa em produo e agregar a ele valor, no por meio da alterao de seu comportamento, mas dando a ele mais destas qualidades que nos permitem continuar desenvolvendo rapidamente. Durante a fase de refatorao, pode-se aplicar qualquer conceito sobre um bom projeto de software. Pode-se aumentar a coeso, diminuir o acoplamento, separar preocupaes, modularizar as preocupaes do sistema, reduzir o tamanho das classes e funes, escolher nomes melhores, alm de poder remover a duplicao, garantir a expressividade do cdigo e minimizar o nmero de classes e mtodos (MARTIN, 2009). 2.2 CDIGO LIMPO A denio de um bom cdigo no precisa. Do mesmo modo que enfrenta-se diculdades para denir o que arte, no se pode denir um conjunto de parmetros lgicos e mensurveis para delimitar a diferena de qualidade entre cdigos-fonte. Podese considerar aspectos como testabilidade, ecincia, facilidade de modicao, processo pelo o qual foi desenvolvido, entre outros. No livro Clean Code (MARTIN, 2009), o autor entrevistou grandes especialistas em desenvolvimento de software como Ward Cunningham (colaborador na criao do Fit, do Wiki e da Programao Extrema (BECK, 1999)) e Dave Thomas (fundador da OTI - Object Technology International - e muito envolvido no Projeto Eclipse) questionando-os quanto a uma denio para cdigo limpo. Cada um dos entrevistados
4

elaborou respostas diferentes, destacando caractersticas subjetivas, como elegncia, facilidade de alterao e simplicidade, e outras puramente tcnicas, incluindo a falta de duplicaes, presena de testes de unidade e de aceitao e a minimizao do nmero de entidades (ALMEIDA; MIRANDA, 2010). Em certo sentido, um cdigo limpo est inserido em um estilo de programao que busca a proximidade a trs valores: expressividade, simplicidade e exibilidade. Tais termos so utilizados por Kent Beck no livro Implementation Patterns (BECK, 2007) que esto em conformidade com a unidade de pensamento que permeia as respostas dos especialistas (ALMEIDA; MIRANDA, 2010). 2.3 ODORES DE CDIGO Segundo a Wikipdia (2013b), odores de cdigo (do ingls bad smell) qualquer sintoma no cdigo fonte de um programa que possivelmente indique srios problemas em sua concepo. Geralmente no so erros - eles no so cdigos tecnicamente incorretos e no impedem o correto funcionamento do programa. Em fez disto, eles indicam deficincias no projeto que podem vir a atrasar o desenvolvimento ou aumentar o risco de bugs e falhas no futuro. Odores de cdigo so heursticas para indicar quando refatorar, e quais as tcnicas especficas de refatorao devem ser usadas. A seguir, ser feita uma breve explanao sobre os odores de cdigo mais comuns: cdigo duplicado, mtodo longo, classes grandes, lista de parmetros longa, inveja de dados, comentrios e propsito obscuro de variveis e mtodos. 2.3.1 CDIGO DUPLICADO Como o prprio nome diz, cdigo duplicado , simplesmente, o mesmo trecho de cdigo repetido em vrios outros lugares como classes e mtodos. considerado o pior odor de um cdigo, pois quando a lgica do trecho duplicado muda, necessrio alter-la em diversos pontos sistema. Segundo Martin (2009), autores como Dave Thomas e Andy Hunt o chamaram de princpio do No Se Repita (do ingls DRY Don't Repeat Yourself), enquanto Kent Beck o tornou como o centro dos princpios da eXtreme Programming (XP) e o chamou de Uma vez, e apenas uma. A forma mais obvia de duplicao quando voc possui blocos de cdigo idnticos, como se alguns programadores tivessem sado copiando e colando o mesmo
5

cdigo vrias vezes. Nestes casos, deve-se substituir estes trechos por mtodos. Uma das formas mais simples de duplicao so as estruturas aninhadas de switch/case e if/else que aparecem repedidas vezes em diversos mdulos, sempre testando as mesmas condies. Neste caso, deve-se substituir pelo polimorfismo (MARTIN, 2009). 2.3.2 MTODO LONGO O odor de mtodo longo consiste em mtodos que comportam grandes trechos de cdigos, geralmente realizam mais de uma ao, atuam em vrios nveis de abstrao, contm um nmero elevado estruturas condicionais e laos de repetio aninhados, narrado por meio de comentrios de cdigo, entre outras coisas. Segundo Almeida e Miranda (2010), o ideal que cada mtodo seja pequeno o suficiente para facilitar sua leitura e compreenso. Deve-se ter em vista a dificuldade de assimilao de grandes pores de informao durante a leitura e o fato de que nem sempre uma instruo clara. A partir dessas idias, um mtodo ser uma poro curta de cdigo que trabalha com poucas variveis e tem um nome explicativo que espelha a sua funcionalidade. Segundo Fowler et al. (2004), uma boa tcnica para decompor mtodos longos olhar para seus comentrios. Um bloco de cdigo com um comentrio que lhe diz o que ele faz pode ser substitudo por um mtodo cujo nome seja baseado no comentrio. Alm deste, expresses condicionais, condies e laos tambm podem ser decompostos em mtodos menores. 2.3.3 CLASSE GRANDE De maneira anloga, o odor de classe grande apresenta as mesmas deficincias de design de cdigo que o odor de mtodo longo. Logo, do mesmo modo que considerase importante limitar a quantidade de informao que um mtodo transmite ao leitor, quer-se que as classes sejam o menor possvel. Alm de facilitar a leitura e entendimento, programar buscando minimizar o tamanho das classes leva-se a criar unidades coesas e a evitar duplicaes. Segundo Fowler et al. (2004), o tamanho de uma classe deve ser definido atravs do Principio da Responsabilidade nica (do ingls SPR - Single Responsability

Principle). Este principio afirma que uma classe ou mdulo deve ter apenas uma responsabilidade e apenas um motivo para mudar. 2.3.4 LISTA DE PARAMETROS LONGA O nmero de argumentos de um mtodo se torna bastante importante quando se quer mtodos pequenos e com apenas uma tarefa. Se um mtodo recebe muitos argumentos, provavelmente os utiliza para um conjunto de operaes e no uma somente. Listas de parmetros longas so difceis de entender, porque se tornam inconsistentes e difceis de usar e porque voc ir sempre alter-las medida que precisar de mais dados. A maioria das alteraes removida passando-se objetos, porque muito mais provvel que voc precise fazer apenas algumas solicitaes para chegar em um novo dado (FOWLER et al., 2004).
Figura 1 - Exemplo de refatorao de uma lista de parmetros longa

Fonte: Autoria prpria, baseada em Martin (2009)

2.3.5 INVEJA DE DADOS Segundo Martin(2009), os mtodos de uma classe devem ficar interessados apenas nas variveis e funes da classe a qual eles pertencem, e no nas de outras classes. Quando um mtodo usa mtodos de acesso e de alterao de algum outro objeto para manipular os dados dentro deste objeto, o mtodo inveja o escopo da classe daquele outro objeto. Ele queria estar dentro daquela outra classe de modo que pudesse ter acesso direto s variveis que est manipulando. o que chamamos inveja de dados (do ingls, Feature Envy), um dos odores mais comuns em cdigos que apresentam problemas na diviso de responsabilidades entre as classes e alto acoplamento.

Um exemplo clssico deste odor o cdigo conhecido como acidente de trem (do ingls, train wreck), onde uma srie de mtodos do getters so chamadas de forma encadeada, como os vages de um trem.
Figura 2 - Exemplo de refatorao de um cdigo acidente de trem

Fonte: Autoria prpria, baseada em Freeman e Pryce (2012)

O acidente de trem uma violao clssica do estilo Diga, No Pergunte (do ingls, Tell, Dont Ask) ou mais formalmente, Lei de Demeter (do ingls, The Law of Demeter). Segundo Almeida e Miranda (2010), esta lei diz que um mtodo M de uma classe C s deveria chamar um mtodo: da prpria classe; de um objeto criado por M; de um objeto passado como argumento para M; de um objeto guardado em uma varivel de instncia de C. Seguido consistentemente, este estilo produz cdigo mais flexvel, porque ele mais fcil de trocar objetos que executam o mesmo papel. O chamador no v nada da estrutura interna deles ou da estrutura do resto do sistema que est por trs da interface do papel do objeto chamado. Alm disto, ele fora a tornar explcitas e ento nomear as interaes entre os objetos, ao invs de deix-las implcitas na cadeia de getters (FREEMAN; PRYCE, 2012). No entanto, existem alguns casos onde um mtodo mesmo sem violar a Lei de Demeter, tem um grande acoplamento com outra classe. O exemplo da figura 3 no viola esta, pois faz chamadas somente a mtodos de um objeto que lhe foi passado por parmetro. Como se pode-se ver, o mtodo salarioDoMes possui um grande
8

acoplamento com a classe Empregado ao utilizar diversos de seus mtodos, de forma que fica caracterizado uma inveja de dados.
Figura 3 - Exemplo de inveja de dados que no viola a Lei de Demeter

Fonte: (ALMEIDA; MIRANDA, 2010)

2.3.6 COMENTRIOS Um dos odores mais polmicos o de comentrios. Na verdade, um comentrio bem feito ser sempre bem vindo. No entanto, segundo Fowler et al. (2004), surpreendente a frequncia com que se veem cdigos cheios de comentrios e percebe-se que eles esto l porque os cdigos so ruins. Neste contexto, os comentrios so utilizados como desodorante de cdigo que cheira mal. Segundo Martin (2009), os comentrios tendem a mentir para os leitores do cdigo onde eles foram fixados. Nem sempre, e no intencionalmente, mas muito comum. Quanto mais antigo um comentrio for e quanto mais longe ele estiver do cdigo o qual ele descreve, mais provvel ser que esteja errado. O motivo simples: pouco provvel que os programadores consigam mant-los atualizados. Segundo Fowler et al. (2004), uma boa heurstica para evitar o mal uso de comentrios: sempre que se sentir necessidade de escrever um comentrio, deve-se experimentar primeiro tornar o trecho de cdigo mais legvel de modo que qualquer comentrio se torne suprfluo. 1.3.7. PROPSITO OBSCURO Segundo Boswell e Foucher (2009), cdigos devem ser escritos de modo a minimizar o tempo necessrio para sua compreenso. o chamado Teorema Fundamental da Legibilidade. Segundo Martin (2009), nomes em softwares so 90% responsveis pela legibilidade do mesmo. Precisa-se tomar seu tempo para escolh-los
9

sabiamente e mant-los relevantes. Nomes so muito importantes para serem tratados de qualquer jeito. Chama-se de propsito obscuro (do ingls, Obscured Intent), um conjunto de pequenos odores que degradam a legibilidade do cdigo fonte, principalmente, no que se refere a nomes de variveis e mtodos que no revelam seu propsito facilmente, como por exemplo, cdigos que apresentam os nmeros mgicos, ou seja, nmeros cujo significado no est claro; como tambm a notao Hngara, que consiste em nomear as variveis com o prefixos que demonstram o seu tipo. Um bom exemplo de cdigo com propsito obscuro o mostrado na figura 4. bem provvel que um desenvolvedor perca bastante tempo para conseguir entender a lgica contida neste mtodo. Isto, simplesmente, porque o desenvolvedor no se esforou para nomear as variveis de forma clara.
Figura 4 - Exemplo de cdigo com propsito obscuro

Fonte: (MARTIN, 2009)

Por outro lado, o cdigo exibido na figura 5 foi escrito de uma forma bem mais legvel. Fica claro a inteno do desenvolvedor em calcular a pontuao de uma partida de boliche.

10

Figura 5 - Exemplo de cdigo legvel

Fonte: (MARTIN, 2009)

2.4 PROJETO SIMPLES Segundo Sommerville (2007), a insatisfao com abordagens pesadas de desenvolvimento de software, que focam principalmente no planejamento, no projeto e na documentao de um sistema, levou um nmero de desenvolvedores de software da dcada de 1990 a propor novos mtodos, denominados geis. Estes permitiam que a equipe de desenvolvimento se concentrasse no software somente, em vez de em seu projeto e documentao. Geralmente, os Mtodos geis contam com uma abordagem iterativa para especificao, desenvolvimento e entrega de software, e foram criados principalmente para apoiar o desenvolvimento de aplicaes de negcios nas quais os requisitos de sistema mudam rapidamente durante o processo de desenvolvimento. Eles destinam-se a entregar um software de trabalho rapidamente aos clientes, que podem ento propor novos requisitos e alteraes a serem includos nas iteraes posteriores do sistema. Provavelmente, o nome mais conhecido do movimento gil seja o de Kent Beck, idealizador do mtodo gil conhecido como Extreme Programming (XP). Durante a criao do conceito de XP, Beck props um mtodo para criao de software bem projetado conhecido como Projeto Simples. Segundo ele, um projeto simples se seguir, em ordem de relevncia, as seguintes regras (MARTIN, 2009): a) Efetuar todos os testes; b) Sem duplicao de cdigo;
11

c) Expressar o propsito do programador; d) Minimizar o nmero de classes e mtodos. Efetuar todos os testes significa utilizar a metodologia de desenvolvimento guiada por teste (TDD), que consiste em criar testes automticos para cada nova funcionalidade antes mesmo de escrever seu cdigo. Programar utilizando essa metodologia torna os sistemas passveis de testes, isso nos direciona a um projeto que segue o Princpio da Responsabilidade nica, ou seja, um projeto no qual as classes sejam pequenas e de nico propsito. Classes que seguem esse princpio geralmente so mais fceis de testar. Logo, quanto mais testes se criar, mais sero direcionados a construir coisas mais simples de serem testadas. Similarmente, o forte acoplamento dificulta a criao de testes, quanto mais testes se criar, mais ser usado os princpios como o Princpio da Inverso de Dependncia, que diz que as classes devem depender de abstraes e no de detalhes concretos, e frameworks de injeo de dependncia de modo a minimizar este acoplamento. Segundo Martin (2009), ao seguir primeira regra do Projeto Simples, estaro preparados para atingir as demais regras, ou seja, ao dispor de um conjunto de testes, possvel manter o cdigo de um sistema limpo, para isso basta recorrer tcnica de refatorao. 2.5 MTRICAS DE CDIGO FONTE Segundo Almeida e Miranda (2010), as mtricas permitem criar mecanismos automatizveis para deteco de caractersticas obtidas atravs da anlise do cdigofonte. Elas podem ser usadas como pontos de avaliao da qualidade do software. Existem dois tipos de mtricas de cdigo-fonte. Algumas avaliam caractersticas de mtodos e outras de classes. As mtricas de classe so normalmente somas ou mdias dos valores das mtricas de mtodos. Dentre as mtricas selecionadas para este trabalho, pode-se citar: Complexidade Ciclomtica de McCabe: calcula o nmero de caminhos linearmente independentes (ou fluxos) de um mtodo. Quanto menor o valor desta mtrica, mais fcil de assimilar ser o cdigo;
12

Nmero de Classes: calcula o nmero de classes do projeto. Quanto maior o valor desta mtrica, mais provvel ser a alta coeso e a diviso de responsabilidades entre as classes;

Total de Linhas de Cdigo: calcula o nmero de linhas de cdigo de uma classe. Quanto menor o valor desta mtrica, mais provvel ser a alta coeso e a diviso de responsabilidades entre as classes;

Linha de Cdigo por Mtodo: calcula o nmero de linhas de cdigo de um mtodo. Quanto menor o valor desta mtrica, mais legvel e menos coisas far o mtodo.

3 METODOLOGIA Como estudo de caso deste trabalho, foi escolhido o aplicativo Reversi, em sua verso 0.25 Beta. Reversi um aplicativo criado exclusivamente para fins acadmicos, como parte de um trabalho de concluso de curso de graduao (CAMELO, 2011). Escrito na linguagem Java, ele consiste na implementao para computador do jogo de estratgia de tabuleiro de mesmo nome, mas que tambm pode ser conhecido como Othello em algumas regies. Ele foi escolhido principalmente por ser classificado como software legado, ou seja, que no possui testes automatizados; alm disso, ele no foi construdo com boas prticas de projeto, tornando-o um ambiente rico em bad smells; e possuir uma quantidade de linhas de cdigo relativamente pequena, mas adequada para um trabalho como o que se est desenvolvendo. Como ambiente de desenvolvimento, foi utilizada a IDE Eclipse Java EE for Web Developers em sua verso Juno. A fim de obter mtricas para esta pesquisa, foram instalados neste ambiente os plug-ins EclEmma Java CodeCoverage for Eclipse, verso 2.2.1, utilizado para mensurar a quantidade de cdigo coberta por testes; e Metrics for Java projects, verso 1.3.6, utilizado para realizar anlise esttica do cdigo e gerar uma srie de estatsticas da qual se far uso da complexidade ciclomtica de McCabe, do nmero de linhas de cdigo por mtodo, do total de linhas de cdigo das classes e nmero de classes do projeto. Na fase de codificao, foram utilizados os frameworks JUnit, verso 4.8.1, usado para dar suporte a criao de testes automatizados da linguagem de programao
13

Java; e o WindowLicker, verso 1.0.0, usado em conjunto com o JUnit para dar suporte a testes de aceitao atravs da interface de usurio Swing. Por fim, o prprio processo de refatorao como um todo pode ser considerado como parte da metodologia, isto por que ser necessrio seguir um conjuntos de pequenos passos e boas prticas para se obter sucesso ao aplicar a tcnica em qualquer projeto. Ser apresentado este processo, desde a criao de um conjunto slido de testes at a deteco dos principais odores de cdigo e a respectiva heurstica utilizada para refatorao do mesmo.

4 RESULTADOS E DISCUSSO Esta seo tem como objetivo apresentar o sistema legado escolhido como estudo de caso deste trabalho, explicar suas principais caractersticas dando nfase em aspectos da sua arquitetura e qualidade de cdigo. 4.1 ARQUITETURA DO SISTEMA REVERSI Do ponto de vista de projeto e arquitetura, a aplicao Reversi classificada como Desktop e apresenta caractersticas modestas se comparada com os padres atuais de desenvolvimento. Mesmo apenas se passado pouco mais de dois anos desde o seu lanamento, ela aparenta ser bem mais antiga, pois foi construda por desenvolvedores inexperientes, que no faziam uso de uma metodologia de desenvolvimento, utilizandose somente o kit de desenvolvimento Java, em sua verso 1.6.0, e no faz uso de nenhuma API ou framework robusto. Dado estes fatos, j poderamos facilmente classific-la como um sistema legado. No entanto, segundo Feathers (2004), existe uma importante caracterstica que j enquadraria esta aplicao como legada: a ausncia de testes automticos. A arquitetura est dividida em trs camadas principais - Gui ou interface, Domnio e IA. A figura 6 ilustra esta diviso. O pacote Gui est situado na parte superior do diagrama, sua funo agrupar todas as classes de interface grfica. atravs dessas classes que o jogador interage com o jogo posicionando suas pedras no tabuleiro. O pacote situado na parte central do diagrama o de Domnio, sua funo agrupar todas as classes responsveis por controlar as regras de negocio da aplicao. As classes de
14

Domnio armazenam informaes sobre o estado atual do jogo como, por exemplo, pontuao e espaos vagos no tabuleiro. Situado na parte inferior do diagrama, est o pacote de IA (Inteligncia Artificial). Sua funo agrupar todas as classes responsveis por implementar os jogadores virtuais da aplicao, mais especificamente, os algoritmos Poda alfa-beta e Gentico (CAMELO, 2011).
Figura 6 - Diagrama de pacotes do Reversi

Fonte: CAMELO (2011)

4.2 REFATORAO DO SISTEMA REVERSI Nesta seo ser detalhada a metodologia de refatorao do sistema Reversi. 4.2.1 PORQUE REFATORAR Suponha-se, hipoteticamente, que os desenvolvedores de Reversi recebessem hoje uma oferta irrecusvel para migrar seu software para um ambiente web ou alterar sua interface grfica para a interface nativa de algum dispositivo mvel compatvel com as especificaes do projeto. Dado o alto acoplamento e a falta de coeso das classes do sistema, no seria possvel aproveitar a regra de negcio do projeto e utiliz-lo em outra interface. Logo, a soluo mais rpida e obvia seria duplicar o projeto, o que resultaria em dois projetos distintos, o desktop clssico e o com a nova interface. Um problema poderia vir a surgir quando se descobrisse um bug em sua implementao de algoritmo genticos, por exemplo, a correo teria que ser feita em

15

dois lugares (projetos) diferentes, o que implicaria em mais tempo para manter o sistema ou inconsistncia das correes nos projetos. Portanto, segundo Fowler et al. (2004), quando descobre-se que tem que acrescentar uma caracterstica a um programa e o cdigo desse programa no est estruturado de forma conveniente para tal, primeiro refatore o programa para facilitar o acrscimo da caracterstica e s depois faz-se a adio. 4.2.2 O PRIMEIRO PASSO DA REFATORAO Segundo Fowler et al. (2004), o primeiro passo da refatorao sempre o mesmo, verificar se o projeto possui um conjunto de testes confiveis para o trecho de cdigo que se deseja refatorar. Caso o projeto no possua testes ou possua, mas no sejam confiveis, cria-se seu prprio conjunto de testes. essencial para a refatorao que se tenha um bom conjunto de testes, pois eles diro se for introduzido alguma falha durante este processo. Para criao dos cenrios de testes foi utilizada a tcnica de modelagem de teste baseado na especificao, conhecida como Particionamento de Equivalncia. Esta tcnica consiste em dividir as entradas do sistema em conjuntos que produzem a mesma sada. Para cada conjunto de entradas especificado um teste. Para o Reversi, foi criado o particionamento como o mostrado na figura 7. Nela, foi dividido o conjunto de entradas entre jogadas boas, jogadas ruins e jogadas boas e ruins, e o conjunto de sadas entre vitrias, empates e derrotas.
Figura 7 - Particionamento de equivalncia para o Reversi

Fonte: Autoria prpria

16

A partir desta especificao foram criados um conjunto de testes de aceitao para o sistema. Testes de aceitao so testes automticos que exercitam o sistema da perspectiva do usurio, ou seja, como se ele estivesse interagindo com o sistema. Para que isto fosse possvel, foi utilizado o framework WindowLicker em conjunto com o JUnit. Assim, os testes interagem com a aplicao clicando nos locais da tela do sistema que foram programados, realizando jogadas e validando cada comportamento resultante da mesma. Este conjunto de testes pode ser visto na figura 8. Como possvel observar, devido a dificuldade de se obter um conjunto de jogadas que faa a partida terminar empatada, o teste que cobre a situao de empate foi descartado.
Figura 8 - Conjunto de testes automticos do Reversi

Fonte: Autoria prpria

Por fim, vale apena ressaltar um problema ocorrido neste primeiro passo. Para se construir testes automticos para um sistema, o mesmo deve ser passvel de teste, ou seja, ele deve prover mecanismos para que seja possvel simular ou prever seu comportamento. No caso do Reversi, as jogadas realizadas pelo computador so imprevisveis, haja vista que as mesmas empregam uma regra de negcio complexa. Assim, seria muito difcil automatizar as jogadas de um usurio sem saber o conjunto de jogadas do computador. A soluo substituir o computador real por um computador de
17

teste (ou computador Stub1). Em sistemas no passveis de teste isto muito vezes no possvel por conta do alto acoplamento entre as classes. Portanto, antes de criar este conjunto de testes, foi necessrio realizar uma pequena alterao no projeto, colocando um pequeno trecho de cdigo de teste no cdigo do sistema. Isto no recomendvel, mas foi necessrio para a realizao deste trabalho. 4.2.3 O PROCESSO DE REFATORAO Agora que o projeto do Reversi j possui um conjunto slido de testes, est-se apto para comear a refatorar qualquer trecho de cdigo que esteja coberto por estes testes. O processo de refatorao deve seguir os seguintes passos: a) Explorar o cdigo do sistema em busca de algum odor; b) Realizar a refatorao de um pequeno trecho do cdigo fedorento; c) Executar o conjunto de testes automticos (ou teste de regresso) para se certificar de que as alteraes no comprometeram o sistema; d) Caso os testes tenham sido executados com sucesso, siga para o passo a; caso contrrio, desfaa suas alteraes e volte ao passo b. O primeiro trecho de cdigo que chamou ateno o da figura 9. Apesar de ser relativamente pequeno, ele um verdadeiro ecossistema de pequenos odores. A comear pelo nome, que apesar de ser legvel, no segue a conveno da linguagem para nomes de mtodos, pois no comea com verbo para indicar uma ao. Existe um alto acoplamento em se instanciar as classes Busca e Populao, alm disso, elas so usadas somente neste mtodo, o que pode ser um indcio de responsabilidade mal posicionada. O mtodo realizaJogada recebe dois parmetros quando poderia simplesmente receber um nico objeto: Jogada. Os comentrios so usados de forma a minimizar o odor do cdigo mal escrito, ora usado para esconder cdigo morto, ora usado de forma redundante para descrever o funcionamento do mtodo. Pode-se ver tambm uma pequena Inveja de Dados na expresso condicional. Assim como, o mtodo realiza duas aes, busca a jogada e depois a executa. Por ltimo, existe um erro de lgica no comando condicional if/else: se

Segundo InfoQ (2013), stub um objeto falso utilizado, no lugar de um objeto real, para propsito de testes. Ele fornece respostas pr configuradas para as chamadas que lhe so feitas durante os testes e normalmente no respondem a nada que no esteja programado para o teste.

18

o mtodo getStrIntelignciaArtificial retornar nulo, por exemplo, o sistema ir escolher o algoritmo minimax alfa-beta, quando deveria tomar outra ao.
Figura 9 - Mtodo buscaJogadaComputador com vrios odores

Fonte: Autoria prpria

Aps

refatorao,

mtodo

anteriormente

denominado

buscaJogadaComputador ficou bem mais intuitivo, como mostra a figura 10. Alm de um nome mais legvel, ele agora executa somente uma ao, e a executa de forma bem feita.
Figura 10 - Refatorao do antigo mtodo buscaJogadaComputador

Fonte: Autoria prpria

A responsabilidade de instanciar a inteligncia artificial da aplicao foi transferida para um mtodo de fbrica, como mostra a figura 11. Nela, tambm possvel ver a correo da lgica do comando condicional if/else, e um exemplo de comentrio de cdigo benfico, sinalizando um dbito tcnico.

19

Figura 11 - Mtodo de fbrica obterComputador

Fonte: Autoria prpria

O segundo trecho de cdigo que chamou ateno foi o da figura 12. Alm de uma srie de nomeaes de mtodos que no seguem a conveno da linguagem, tem-se um caso tpico de Inveja de Dados, mais precisamente nas chamadas dos mtodos fimJogo, isVezJogado e resultadoJogo. Apesar de no violar a Lei de Demeter, est claro que este trecho de cdigo inveja os dados do objControle.
Figura 12 - Inveja de dados do objeto objControle

Fonte: Autoria prpria

A soluo posicionar a responsabilidade de obter a mensagem com status atual do jogo na classe correta, ou seja, na classe ControladorDoJogo como mostra a figura 13.

20

Figura 13 - Responsabilidade reposicionada na classe ControladorDoJogo

Fonte: Autoria prpria

Alm da falta de legibilidade dos nomes de variveis e mtodos, e h um excessivo nmero de comentrios que insistem em explicar o que os nomes ruins do mtodo no conseguem. Um dos odores que mais vem se repetindo no cdigo do Reversi o Acidente de Trem e a duplicao de cdigo que sempre o acompanha. A figura 14 mostra claramente a repetio de cdigo causada pelo Acidente de Trem ao chamar as funcionalidades do objeto objControle. Por fim, outro odor que est comeando a cheirar forte neste trecho de cdigo, devido a grande quantidade de nmeros mgicos e notao Hngara, o chamado Propsito Obscuro.
Figura 14 - Cdigo Acidente de trem ao chamar mtodo getMatPedrasTabuleiro

Fonte: Autoria prpria

A soluo para este tipo de odor consiste basicamente em delegar para a classe colaboradora mais prxima a responsabilidade de prover a funcionalidade que se estava interessado ao fazer o Acidente de Trem. No caso especifico, foi delegado a classe ControladorDoJogo a obteno do caminho da imagem, como mostra a figura 15. Esta
21

refatorao tambm ir resolver o problema de duplicao de cdigo ocorrido ao se chamar o mtodo getMatPedrasTabuleiro, pois agora existir apenas uma nica chamada a este mtodo, centralizada em uma classe que possua tal responsabilidade. Tambm foram removidos os nmeros mgicos com constantes explicativas e renomeadas as variveis de forma mais legvel. Por fim, vale lembrar que o trecho de cdigo da figura 14 acabou sendo extrado para um mtodo que explicar claramente seu propsito, chamado gerarTabuleiroLabelComEstadoAtualDoJogo.
Figura 15 - Refatorao do Acidente de Trem do mtodo getMatPedrasTabuleiro

Fonte: Autoria prpria

Um mtodo que tambm chamou ateno foi o executaJogada, que possua 191 linhas de cdigo, como mostra a figura 16. Logo, no resta nenhuma dvida de que este mtodo realiza mais de uma ao. Alm disso, mesmo ocultando a maior parte do cdigo contido no mtodo, possvel imaginar que ele continha uma quantidade elevada de odores.

22

Figura 16 - Muitas linhas de cdigo no mtodo executaJogada

Fonte: Autoria prpria

A soluo para este problema foi remanejar as responsabilidades deste mtodo, ora utilizando uma extrao de trechos de cdigo para um mtodo menor com propsito claro, ora criando novas classes para realizar funes especficas. De acordo com os comentrios da figura 16, a responsabilidade de executaJogada atualizar o estado do tabuleiro, invertendo as cores das pedras afetadas aps uma jogada. A refatorao deste mtodo pode ser vista na figura 17. Foram criadas vrias classes do tipo Reversvel que implementam o mtodo reverter de acordo com a direo (ou sentido) do tabuleiro que se deseja atualizar.
Figura 17 - Refatorao do mtodo executaJogada

Fonte: Autoria prpria

4.2.4 QUANDO PARAR DE REFATORAR No existe uma condio de parada exata para determinar quando a refatorao termina, haja vista que tudo depende da sensibilidade e necessidades do desenvolvedor que a executa. No caso do Reversi, o objetivo foi seguir apenas a Regra do Escoteiro (do ingls, The Boy ScoutRule), uma metfora que segundo Martin (2009), diz: Deixe a rea do acampamento mais limpa do que como voc a encontrou.

23

Fazendo uma analogia para programao, se cada desenvolvedor deixar o cdigo fonte do sistema em que est trabalhando mais limpo do que quando o recebeu de outro programador, ele estar atendendo Regra. Portanto, este processo de refatorao foi repetido vrias vezes consecutivas at que todo o cdigo do Reversi, que estava coberto por testes, estivesse melhor que o cdigo original. 4.3 MTRICAS DO SISTEMA REVERSI Com o intuito de mensurar os ganhos de qualidade advindos do processo de refatorao, foi realizada a coleta das mtricas escolhidas para o projeto Reversi. Elas foram coletadas durante os trs marcos deste processo, so eles: a) Aps posse do sistema legado, ou seja, antes da refatorao ser aplicada; b) Aps a criao do conjunto de testes de aceitao; c) Aps o processo de refatorao chegar ao fim. As mtricas coletadas podem ser vistas na figura 18. Como pode-se ver, as quatro primeiras mtricas referentes a complexidade ciclomtica 1 e linhas de cdigo avaliam o projeto no escopo de mtodo. Nelas, o processo de refatorao reduziram seus nmeros iniciais aproximadamente pela metade (com exceo da complexidade ciclomtica mxima que teve uma reduo muito maior). Isto significa que os mtodos do projeto esto mais coesos, realizam menos aes e esto mais legveis.

Complexidade ciclomtica (ou complexidade condicional) uma mtrica de software usada para indicar a complexidade de um programa de computador. Desenvolvida por Thomas J. McCabe em 1976, ela mede a quantidade de caminhos de execuo independentes a partir de um cdigo fonte (WIKIPDIA, 2013c).

24

Figura 18 - Mtricas do projeto Reversi

Fonte: Autoria prpria

As mtricas seguintes, total de classes e mdia de linhas de cdigo das classes, avaliam o projeto no escopo de classes. Percebe-se que os nmeros se contrapem em propores bastante semelhantes, enquanto o total de classes do projeto teve um aumento pouco maior que o dobro em relao aos nmeros iniciais, a mdia de linhas de cdigo das classes do projeto teve seus valores reduzidos pela metade em relao aos nmeros iniciais. Isto significa que as responsabilidades das classes foram melhor divididas atravs da criao de mais classes e a coeso das mesmas aumentada pela menor quantidades de linhas que elas apresentam. Por fim, as mtricas de cobertura de testes nos mostram a porcentagem de linhas de cdigo do projeto coberta por testes. Como pode-se ver, o projeto saiu do patamar de projeto legado, ou seja, que no possui cdigo coberto por testes, para um projeto com 49,4% do seu cdigo coberto por testes. Vale lembrar que este conjunto de testes cobrem apenas os pacotes Gui e Domnio do projeto, ficando o pacote IA sem testes e, consequentemente, sem refatorao. Isto aconteceu porque foi necessrio substituir o computador real por um computador de teste (ou computador Stub) durante a execuo dos testes. Assim, o fluxo de execuo do programa, que passava pelo pacote IA, foi desviado para um pacote de testes previamente configurado.

25

5 CONCLUSO Este artigo sugeriu a utilizao da tcnica de refatorao para melhorar a qualidade de cdigo de sistemas legados, com o intuito de avaliar se os benefcios advindos de sua utilizao so satisfatrios o bastante para adot-la no processo de evoluo deste tipo de sistema, tornando-os mais produtivos e permitindo que suas melhoria e manuteno sejam efetuadas com rapidez e segurana. Ao final do processo de refatorao foi constatado, com base em um conjunto de mtricas de software, que a qualidade do projeto aumentou consideravelmente. As classes se tornaram mais coesas e suas responsabilidades foram melhor divididas. Os mtodos perderam boa parte de sua complexidade e tamanho, e agora realizam aes mais especficas. Alm disso, ganharam maior legibilidade. Por fim, o projeto ganhou um conjunto de testes automticos que podem ser executados a qualquer momento, permitindo que o sistema possa evoluir com segurana e rapidez. Tendo em vista os fatos mencionados, considera-se a tcnica de refatorao importante para a melhoria da qualidade de sistemas legados, tornando-os mais produtivos e permitindo que melhorias e evolues sejam efetuadas com um menor risco.

REFERNCIAS ALMEIDA, Lucianna Thomaz; MIRANDA, Joo Machini de. Cdigo Limpo e seu Mapeamento para Mtricas de Cdigo Fonte. Trabalho de Concluso de Curso Instituto de Matemtica e Estatstica, Universidade de So Paulo - USP. So Paulo, 2010. BECK, Kent. Extreme Programming Explained. Boston: Addison Wesley, 1999. BECK, Kent. Implementation Patterns. Boston: Addison Wesley, 2007. BOSWELL, Dustin; FOUCHER, Trevor. A Arte de Escrever Programas Legveis: tcnicas simples e prticas para elaborao de programas fceis de serem lidos e entendidos. Trad. Rafael Zanolli. So Paulo: Novatec, 2012.
26

CAMELO, Anderson Lemos. Um Jogo de Othello Evolutivo. Trabalho de Concluso de Curso (Graduao em Cincias da Computao) - Instituto de Computao, Universidade Federal de Alagoas - UFAL, Macei, 2011. FOWLER, Martin; BECK, Kent; BRANT, John; OPDYKE, Willian; GAMMA, Erich. Refatorao: aperfeioando o projeto de cdigo existente. Trad. Acauan Fernandes. Porto Alegre: Bookman, 2004. FEATHERS, Michael C. Working Effectively with Legacy Code. UpperSaddle River: Prentice Hall, 2004. FREEMAN, Steve; PRYCE, Nat. Desenvolvimento de Software Orientado a Objetos, Guiado por Testes. Trad. Savannah Hartmann. Rio de Janeiro: Alta Books, 2012. INFOQ. Mocks Aren't Stubs. 2013. Disponvel em: <http://www.infoq.com/br/articles/mocks-Arent-Stubs>. Acesso em: 28 set. 2013. MARTIN, Robert C. Cdigo Limpo: habilidades prticas do agile software. Trad. Leandro Chu. Rio de Janeiro: Alta Books, 2009. SARTORELLI, Reinaldo Coelho. Proposta de Processo para Automao de Testes em Sistemas Legados. Trabalho de Concluso de Curso (Ps-Graduao em Tcnicas de Construo de Software Orientado a Objetos) - Centro Universitrio SENAC, So Paulo, 2007. SOMMERVILLE, Ian. Engenharia de Software. Trad. Selma Shin Shimizu Melnikoff, Reginaldo Arakaki, Edilson de Andrade Barbosa. So Paulo: Pearson Addison-Wesley, 2007. WIKIPDIA. Refatorao. 2013a. Disponvel em: <http://pt.wikipedia.org/wiki/Refatorao>. Acesso em: 17 set. 2013. WIKIPDIA. CodeSmell. 2013b. Disponvel em: <http://http://en.wikipedia.org/wiki/Code_smell>. Acesso em: 17 set. 2013. WIKIPDIA. Complexidade ciclomtica. 2013c. Disponvel em: <http://pt.wikipedia.org/wiki/Complexidade_ciclomtica>. Acesso em: 28 set. 2013.

27

Anda mungkin juga menyukai