Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 Utilizando a Refatoração para Reorganizar Estruturas de Código Andrio dos Santos Pinto Universidade do Vale do Rio dos Sinos – UNISINOS Programa Interdisciplinar de Pós-Graduação em Computação Aplicada - PIPCA São Leopoldo – RS - Brasil andriosp@gmail.com Resumo Refatoração é o processo de mudar um software de tal forma que melhore a sua estrutura interna sem, contudo, alterar o seu comportamento externo. É, portanto, uma forma disciplinada de reorganizar o código, minimizando as chances de introduzir erros. Refatorar tem a vantagem de melhorar a estrutura do código, facilitando o seu reuso e diminuindo o tempo gasto com tarefas de manutenção. Este trabalho mostra um breve tutorial sobre o tema proposto. Palavra-chave: Refatoração 1. Introdução O presente artigo tem por objetivo maior apresentar a refatoração como um tutorial, de forma a fazer com que o leitor entenda melhor sua função, seus objetivos e suas aplicabilidades, bem como seus benefícios e desvantagens. Além da Introdução, o artigo está organizado em mais sete seções, descritos a seguir: Na Seção 2, é feito algumas definições sobre refatoração, seus principais objetivos, suas utilizações, seus benefícios e insuficiências, e a descrição do seu processo. Na Seção 3, apresenta-se um histórico sobre alguns dos principais escritores sobre refatoração. Na Seção 4, descrevem-se os principais tipos de refatoração, segundo o livro de Martin Fowler. Na Seção 5, demonstram-se alguns exemplos onde ocorreram refatoração. Na Seção 6, são discutidas as principais ferramentas desenvolvidas. Por fim, na Seção 7, é feito uma conclusão sobre o artigo. 2. O que é Refatoração? Algumas definições sobre refatoração de diferentes autores: - Processo pelo que os programadores reestruturam o sistema sem mudar suas funcionalidades para remover duplicidades, melhorar a comunicação, simplificar ou adicionar flexibilidade [8]. - Processo de melhorar a estrutura do código preservando sua funcionalidade [8]. - Processo de mudar um software de forma que o comportamento externo do código não seja alterado mesmo que sua estrutura interna seja incrementada [6]. - Processo de reorganizar o projeto de um sistema para torná-lo mais flexível e/ou reusável [6]. Ao implementar uma funcionalidade do programa, os programadores sempre perguntam se há algum jeito de mudar o programa existente para adicionar esta funcionalidade. Após ter adicionado esta funcionalidade, os programadores perguntam se agora eles conseguem ver como fazer o programa mais simples, mas ainda rodando todas as funcionalidades. Isto é refatoração [8]. 2.1 Objetivos Os principais objetivos da refatoração segundo Eliane Martins [6] são: - Tornar o código mais claro, limpo, simples e elegante; - Permitir que componentes mais simples ou expressões mais eficientes sejam usadas. 2.2. Utilização Kent Beck [7, p.60], um dos criadores da Programação Extrema (Extreme Programming), afirma 2 que refatoração deve ser utilizada quando o “código cheira mal” (do inglês bad smells in code). Alguns indícios já possuem uma aceitação ampla para promover refatoração [7]: - Método longo; - Classe grande; - Lista de parâmetros longa; - Quando o código não estiver claro; - Melhorar a legibilidade; - Separar a lógica existente da alteração necessária; - Substituir um algoritmo por outro; - Melhorar o desempenho. Já no contexto da evolução de software, a refatoração é usada para melhorar os atributos de qualidade do software, como extensibilidade, modularidade e reusabilidade, entre outros. A refatoração também pode ser usada no contexto da reengenharia, ou seja, para alterar um sistema específico visando reconstruí-lo em um novo formato. Nesse contexto, para refatorar é necessário converter código legado ou deteriorado em um formato mais estruturado ou modular, ou para migrar o código para uma diferente linguagem de programação, ou mesmo um diferente paradigma de linguagem [12]. Refatorações também podem ser aplicadas em diferentes níveis de abstração e tipos de artefatos de software. Por exemplo, é possível aplicar refatorações a modelos de projeto, esquemas de banco de dados, requisitos, e arquitetura de software [13]. Essa diversidade possibilita ao desenvolvedor realizar mudanças estruturais que não necessariamente se refletem no código fonte e, portanto, introduzem a necessidade de manter todos os artefatos em sincronia. Nas subseções seguintes detalharei os três níveis de abstração nos quais podemos aplicar refatorações [12]. 2.2.1 Nível de análise Nesse nível, as alterações são consideradas reestruturações, pois não são descritas em termos de código fonte. Um exemplo de reestruturações nesse nível são mudanças na especificação dos requisitos de software. Alessandra Russo [18] sugere reestruturar essas especificações decompondo-as em uma estrutura de pontos de vista (view points), que encapsulam requisitos parciais de algum componente do sistema. Essa abordagem aumenta o entendimento dos requisitos, facilita a detecção de inconsistências e permite um melhor gerenciamento da evolução dos requisitos [12]. 2.2.2 Nível de projeto Novas pesquisas em refatorações se direcionam para artefatos de projeto de software. Para arquiteturas de software, podemos destacar duas abordagens: a primeira propõe pré-condições de refatorações, que preservam o comportamento do sistema através da relação de causa entre os componentes, baseadas diretamente em representações gráficas da arquitetura do sistema [15]. A segunda é mais pragmática e propõe que mudanças na arquitetura possam ser feitas através uma seqüência de refatorações primitivas [20]. Outro tipo de artefato de projeto são modelos de projeto de software. Em particular, modelos UML têm sido largamente utilizados como mecanismo de projeto de software [12]. Padrões de projeto estão cada vez mais sendo usados por desenvolvedores. Eles fornecem uma maneira de escrever o programa em um nível de abstração mais alto. Padrões de projeto criam várias oportunidades de aplicação de refatoração [12]. 2.2.3 Nível de código Essa é forma mais comum de se aplicar refatoração a um sistema. Refatorações podem ser aplicadas a diversas entidades do código, e às mais variadas linguagens de programação e paradigmas de linguagem, como por exemplo, linguagens imperativas (Fortran, Cobol), funcionais (Liso, Haskell), lógicas (Prolog), orientadas a objeto (Smalltalk, C++, Java) e orientadas a aspectos (AspectJ) [12]. Linguagens não orientadas a objeto são mais difíceis de se reestruturar, pois fluxos de controle e de dados são fortemente interligados e, por causa disso, as reestruturações são limitadas ao nível de função ou bloco de código [10]. Contudo, linguagens puramente orientadas a objeto apresentam características que tornam algumas refatorações extremamente trabalhosas para serem implementadas, como é o caso das refatorações que lidam com herança, polimorfismo, ligação dinâmica e interfaces. Além disso, quanto mais complexa a linguagem, maior a dificuldade de implementar refatorações. Esse é o caso de programas escritos em C++, que após serem pré-processados perdem muitas informações estruturais, impossibilitando ou reduzindo o escopo de aplicação de refatorações [12]. 2.3 Benefícios Adiciona qualidade ao sistema, pois [7, p. 60]: - redução de código duplicado; - aumenta a simplicidade; - facilita a leitura; - melhora a performance. 2.4 Vantagens - Manutenibilidade 3 É mais fácil manter um sistema quando o código está “limpo” [6]. - Eficiência Exemplo: Seja a expressão: (x-1)*(x+1) = x^2-1 Qual é a mais eficiente? Lado esquerdo. Por que? Usa operações mais simples apesar de possuir mais termos e operadores [6]. 2.5 Insuficiências da Refatoração Martin Fowler devota uma seção de seu livropara os problemas levantados quando fazemos refatoração, que é para a maioria de nós uma técnica nova [14]. Quando você aprende uma técnica nova que melhora extremamente sua produtividade, é duro ver quando ela não se aplica. Geralmente você a aprende dentro de um contexto específico, em apenas um simples projeto. É duro ver o que causa as técnicas serem menos eficazes, prejudiciais [7, p.62]. Ao trabalhar com refatoração em bases de dados relacional que movem os dados para algum lugar é caro implementá-los, os esquemas da base de dados também têm que ser modificados. Isto pode ser parcialmente evitado, separando a base de dados e as aplicações por uma camada de ação indireta, a qual pode ser modificada para refletir as mudanças sem tocar na base de dados [14]. Se as bases de dados do objeto ajudarem com a migração de versões do objeto, é somente uma questão do tempo adicional necessário. Se não a migração será feita manualmente [14]. Muitas refatorações negociam com as mudanças de nome e lugar do método, de modo a mudar a interface da classe interessada. Contanto que esta interface for usada somente dentro de seu próprio sistema, você tem que encontrar e mudar todos os usuários da interface, lá a posse coletiva do código é mais útil [14]. Se a interface já é usada por uma classe fora do escopo, ela evolui além da interface pública, para torná- la publicada [7, p 64]. Isto introduz a necessidade de manter a interface velha viva, quando já publicar a refatoração da interface nova. Isto pode ser realizado por delegações dos métodos deprecados aos novos [14]. Consequentemente deve ser evitado publicar interfaces prematuras. Deixá-las evoluir durante o processo do desenvolvimento sem conter a flexibilidade – necessária para reservar refatoração – publicando-as [14]. 2.6 Processo de Refatoração A maioria das ferramentas de refatoração segue um processo comum, no qual operações de refatoração são aplicadas ao código-fonte dos programas de acordo com passos bem definidos [13]. Em geral, esses passos incluem [12]: 1. Detectar trechos do código com oportunidades de refatorações. 2. Determinar que refatorações aplicar a cada trecho do código selecionado. 3. Garantir que as refatorações escolhidas preservem o comportamento. 4. Aplicar as refatorações escolhidas aos seus respectivos locais. 5. Verificar que o comportamento do programa foi preservado após as refatorações terem sido aplicadas. Figura 1 – Processo de Refactoring [1] 3. Histórico O primeiro trabalho mais relevante publicado nessa área foi a tese de William Opdyke, a qual trata de refatorações para programas escritos em C++. Ele definiu vinte e três refatorações primitivas e mostrou três exemplos de refatorações compostas, formadas por duas ou mais primitivas. Para cada refatoração primitiva, o trabalho introduz um conjunto de pré- condições que fornecem a noção de preservação do comportamento do sistema. As refatorações primitivas definidas por Opdyke foram classificadas nas quatro categorias abaixo [12]: - Criação de entidades. - Remoção de entidades. - Alterar entidade. - Mover variável. 4 As refatorações compostas foram: - Abstrair acesso a uma variável. - Converter segmento de código para função. - Mover classe. Opdyke também identificou sete propriedades que uma refatoração deve obedecer para preservar o comportamento, também chamadas de invariantes: cada classe deve ter uma única superclasse; cada classe deve ter nome distinto das outras classes; os membros de uma classe (variáveis e métodos) devem ter nomes distintos; variáveis herdadas não podem ser redefinidas; funções herdadas devem ter a mesma assinatura da função original; atribuições de tipo seguras que consiste em forçar que o tipo da expressão do lado esquerdo de uma atribuição seja igual ou um subtipo da expressão contida no lado direito; equivalência semântica de operações e referências, isto é, um programa deve produzir a mesma saída para uma dada entrada antes e depois de se aplicar a refatoração. Lance Tokuda [20] se baseou no trabalho de Opdyke para ir mais além e avaliar projetos orientados a objeto com refatorações. Primeiramente, ele definiu mais quatro propriedades (invariantes) que uma refatoração deve obedecer para preservar o comportamento e que não foram previstas por Opdyke, a seguir: implementação de funções puramente virtuais; manter objetos agregados; nenhum efeito colateral de instanciação; e independência de layout ou tamanho. Sua pesquisa também mostrou que todos os tipos de evolução de projeto, isto é, transformações de esquema, micro arquiteturas de padrões de projeto e abordagem dirigida a hot-spot, são automatizáveis com refatorações, e propôs, então, uma série de novas refatorações para cada tipo de evolução. Tokuda também fez experimentos para avaliar se a aplicação de refatorações para programas C++ já existentes, cujo código ultrapasse mais de 100.000 linhas, é viável. Suas conclusões mostram que a aplicação de refatorações traz muitos benefícios, entre os quais estão automatização das mudanças no projeto, redução de testes, e criação de projetos mais simples. Donalds B. Roberts [17] se concentrou em propor um arcabouço para linguagens orientadas a objeto, que permite a criação de ferramentas de refatoração confiáveis e rápidas o suficiente para serem usadas na prática por desenvolvedores. Como resultado, desenvolveu uma das primeiras ferramentas de refatoração, o Refactoring Browser, para a linguagem Smalltalk. Roberts também estendeu o conceito de refatoração de Opdyke acrescentando pós-condições que cada refatoração deve obedecer. Essas pós-condições descrevem o que deve ou não haver depois da aplicação da refatoração e podem ser usadas para derivar pré- condições de refatorações compostas, calcular dependência entre refatorações e reduzir a quantidade de análises que refatorações posteriores em uma seqüência devem realizar para garantir que preservam o comportamento. Baseado nesse novo conceito, ele redefiniu algumas refatorações propostas por Opdyke, e as dividiu em três grupos: - Refatorações de classe. - Refatorações de métodos. - Refatorações de variáveis. Sander Tichelaar [19] implementaram 15 refatorações primitivas independentes de linguagem de programação, definindo um conjunto de pré-condições que podem ser aplicadas a qualquer linguagem. Porém, para algumas refatorações, é necessário acrescentar precondições específicas da linguagem para que o comportamento realmente seja preservado. Fowler [7] se focou em outra direção, diferente de Opdyke e Roberts: o processo de refatoração. Ele explica princípios e melhores práticas de refatoração, além de fornecer um guia sobre o processo de refatoração (onde começar, quando começar, quando parar) e um extenso catálogo de refatorações. Contudo, ele não define as condições que garantem que as refatorações preservam o comportamento. Com o crescimento do uso de padrões de projetos, muitos pesquisadores passaram a estudar as oportunidades de refatorações inerentes a cada padrão. Mel Ó Cinnéide [5] desenvolveu uma metodologia para desenvolvimento de transformações de padrões de projeto baseadas em refatorações. Essa metodologia tem sido aplicada para sete padrões e é implementada através de uma ferramenta para código Java [12]. Outra metodologia que foi responsável pelo crescimento da visibilidade de aplicar refatoração foi Extreme Programming (XP), pois uma de suas principais idéias é que o desenvolvedor deve trabalhar em apenas um caso de uso por vez e assim deve projetar o software para que fique coerente com o caso de uso em questão. Se um determinado caso de uso não ficou bem projetado, deve-se aplicar refatorações até que o caso de uso possa ser implementado de uma maneira coerente. Ao contrário de tentar evitar mudanças, XP é uma metodologia que é baseada em mudanças.Um dos principais pilares de XP é a contínua e agressiva aplicação de refatorações. Sem elas, XP não funcionaria. 4. Tipos de Refatoração As refatorações descritas no livro de Martin Fowler utilizam fortemente conceitos de orientação a objeto. Bastam observar algumas [22]: 5 - Extrair método (Extract Method); - Mover método (Move Method); - Mover atributo (Move Field); - Extrair classe (Extract Class); - Encapsular atributo (Encapsulate Field); - Renomear método (Rename Method); - Subir método (Pull Up Method); - Descer método (Push Down Method); - Descer atributo (Push Down Field); - Extrair Sub-classe (Extract Subclass); - Extrair Super-classe (Extract Superclass). 5. Exemplos 5.1 Exemplo 1 Foi criada uma classe chamada S com os atributos e métodos semelhantes e separado as duas classes A e B. Figura 2 – Refatoração em clases [6] 5.2 Exemplo 2 Foi criado um bloco de Dados comuns ligando os demais blocos que antes eram ligados por um bloco de dados globais. Antes: Figura 3 – Bloco de dados antes da refatoração [6] Depois: Figura 4 – Refatoração em bloco de dados [6] 5.3 Exemplo 3 Foi criada duas novas classes BancoDeDadosFactory e BancoDeDadosConcreteCreator. Sendo que a primeira aponta para a classe BancoDeDados e herda da segunda, e a segunda cria uma herança para a classe Cliente. Antes: Figura 5 – Classes de um sistema OO fictício antes da aplicação das refatorações [12] Depois: Figura 6 – Nova estrutura de classes após a aplicação de refatorações [12] 6 5.4 Exemplo 4 O código Java abaixo demonstra a aplicação da refatoração para extrair método (Extract Method) [ 22]. Antes: /** Salva o produto no banco de dados. */ public void save() { // Verifica propriedades if (this.getName() == null) { throw new Exception("Falta nome"); } else if (this.getDescription() == null) { throw new Exception("Falta a descrição"); } this.getDatabase().save(this); } Depois: /** Salva o produto no banco de dados. */ public void save() { this.checkProperties(); this.getDatabase().save(this); } /** Verifica as propriedades do produto. */ public void checkProperties() { if (this.getName() == null) { throw new Exception("Falta nome do produto."); } else if (this.getDescription() == null) { throw new Exception("Falta a descrição do produto."); } } 6. Ferramentas Apesar de podermos aplicar refatorações manualmente, ferramentas que automatizem o processo diminuem o risco de erros e inconsistência no código, além de poupar um grande trabalho em se tratando de sistemas com centenas ou milhares de linhas de código [12]. A primeira ferramenta de refatoração desenvolvida foi o Smalltalk Refactoring Browser [17]. Projetada para auxiliar programadores da linguagem Smalltalk, esta ferramenta tornou o processo de refatoração mais rápido e satisfatório. Porém, como Smalltalk não é uma linguagem comercial, seu uso ficou restrito, já que poucas pessoas utilizam essa linguagem hoje em dia, embora a ferramenta tenha muitas funcionalidades [12]. Desde então, muitas ferramentas de refatoração surgiram, sejam comerciais ou acadêmicas, para diferentes linguagens, como por exemplo, C# Refactory [3] e C# Refactoring Tool [4], para códigos escritos em C#, Project Analyzer [2], para programas em Visual Basic, e Bicycle Repair Man, que é uma tentativa de criar uma ferramenta similar a Refactoring Browser, porém para a linguagem Python [12]. Com a expansão de Java, muitas ferramentas de refatoração para essa linguagem surgiram, sendo X- Refactoring [21] e IntelliJ IDEA [9] as pioneiras. Com o crescimento do número de IDE’s para Java, algumas ferramentas de refatoração foram criadas como plugins para esses ambientes, dentre as quais podemos citar JFactor, RefactorIt, JRefactor, Transmogrify e JavaRefactor. Outras apresentam-se como ferramentas independentes de IDE e trazem algumas funcionalidades de engenharia reversa, como é caso de OptimalJ [12]. No meio acadêmico, Elbereth foi desenvolvida como uma ferramenta de refatoração para código Java baseada no conceito de Diagramas Estrela, que fornece uma visão gráfica das estruturas do código, como forma de melhor representá-lo e manipulá-lo. A grande maioria dessas ferramentas implementa os mesmos tipos de refatoração, dentre os quais estão: extrair métodos e superclasses, renomear variáveis, métodos e atributos, mover para cima e para baixo atributos e métodos na hierarquia de classes. O problema é que elas não possuem o código fonte aberto que possibilite um desenvolvedor estender a ferramenta, ou então, quando possuem, usam representações próprias do código, o que também dificulta a sua extensão, dado que o desenvolvedor deve ter um domínio sobre a manipulação dessa representação. 6.1 XRefactory É uma ferramenta de desenvolvimento profissional para Emacs e Xemacs que permite completar, navegar e refatorar o código [6]. Suas principais características são: Integração total com Emacs e Xemacs; Trabalha nas plataformas Unix (Linux, SunOS- Solaris, HP-UX...) e Windows; Linguagens C e Java; Projetada para trabalhar com projetos grandes; Aceita vários projetos com o sistema de auto- detecção de projetos; Possibilidade de geração de documentação HTML; Extração de métodos (funções); Renomeação de pacotes, classes parâmetros, variáveis, campos (registros de estruturas) e métodos (funções); 7 Inserção, remoção, deslocamento e troca parâmetros; Deslocamento de campos e métodos; Push down e pull up de métodos e campos; Encapsulamento de campos entre outros; Detecção de possíveis conflitos. 6.2 Xref É uma ferramenta de referência cruzada para C e Java [6]. Funciona da seguinte maneira: - varre os arquivos de entrada; - verifica as definições e usos de todos os símbolos. Tem por saída: - Lista de símbolos com as posições de suas declarações, definições e usos; - Arquivo HTML. 6.3 C# Refactory C# Refactory executa um grande número de refatorações, permitindo que você reformule seu código c# com as novas necessidades [3]. C# refactory permite automatizar muitas refatorações, aumentando assim a confiabilidade e a velocidade com que você pode refatorar seu código c#. C# Refactory é integrado inteiramente com o IDE – as refatorações estão sempre prontas. 6.4 IntelliJ IDEA IntelliJ IDEA é uma inteligente IDE Java, intensamente focada no desenvolvimento da produtividade. Ela provém uma robusta combinação de uma ferramenta de desenvolvimento, incluindo refatoração, suporta J2EE, ANT, JUnit, e versões de controle da integração. IntelliJ IDEA habilita programadores Java impulsionando sua produtividade ao reduzir o tempo das tarefas rotineiras [9]. 7. Considerações Finais A Refatoração, como mostrada neste trabalho, não é um processo recente, é uma atividade de manutenção de código, que vem sendo utilizada e desenvolvida por diversos programadores e que atualmente está bem difundida. Assim como qualquer outra técnica, ela possui seus prós e seus contras, mas, é mais eficiente se utilizada com ferramentas automatizadas, pois isto diminui o risco de se introduzir novos erros devido a intervenções manuais, e minimiza a quantidade de testes realizados toda vez que o código é alterado. Já existem várias ferramentas com suporte a variadas linguagens de programação, como Smalltalk, Java e C#. Referências Bibliográficas [1] Alexandre Barros. Home Page. Disponível em http://www.cin.ufpe.br/~abab/ppt/Refactoring.ppt#2 98,7,Processo de Refactoring. Último acesso em 19/5/2006. [2] Avoisto. Project Analizer. Home page. Disponível em http://www.avoisto.com/project/project.html. Último acesso em 19/5/2006. [3] C# Refactory. Home Page. Disponívelem http://www.xtreme- simplicity.net/CSharpRefactory.htm. Último acesso em 19/5/2006. [4] C# Refactoring Tool home page. Disponível em http://dotnetrefactoring.com/. Último acesso em 19/5/2006. [5] Cinnéide, M. O., Automated Apllications of Design Patterns: A Refactoring. Tese (Doutorado em Ciências da Computação), Universidade de Dublin, 2000. [6] Eliane Martins. Home Page. Disponível em http://www.ic.unicamp.br/~eliane/Cursos/Transpare ncias/Manutencao/evolucao6_refat.pdf. Último acesso em 19/5/2006. [7] Fowler, Martin. “Refactoring: Improving The Design of Existing Code”. Adisson Wesley. [8] Herbert Mattei de Borba. Home Page. Disponível em http://www.inf.ufsc.br/~herb/disc/engenharia_de_so ftware. Último acesso em 19/5/2006. [9] IntelliJ IDEA. Home Page. Disponível em http://www.jetbrains.com/idea/index.html. Último acesso em 19/5/2006. [10] Lakhotia, A., Deprez, J. C., “Restructuring Programs by Tucking Statements into Functions”, Information and Software Tecnology, special issue on Program Slicing, vol. 40, pp. 670-689, 1998. [11] Leonardo R. Nunes. Home Page. Disponível em http://www.projava.com.br/wiki/projava/upload/4ev entoprojava2004/PalestraRefactoring_files/frame.ht m. último acesso em 19/5/2006. [12] Maia, Paulo H. Mendes. “REFAX: Um arcabouço para desenvolvimento de ferramentas de refatoração baseado em XML”. Dissertação – Programa de Pós- Graduação em Ciência da Computação, UFC, Fortaleza, Ceará. [13] Mens, T. and Tourwé, T. “A Survey of Software Refactoring”. IEEE Transactions on Software Engineering, Vol. 30, No. 2, February 2004. [14] Michael Hunger. Home Page. Disponível em http://emw.inf.tu- dresden.de/de/pdai/Forschung/refactoring/refactorin 8 g_html/node16.html#SECTION0034000000000000 0000. Último acesso em 19/5/2006. [15] Philipps, J., Rumpe, B., “Refinement of Information Flow Architectures”, in Proc. of International Conference on Formal Languages and Methods, 1997. [16] Refactoring. Home Page. Disponível em http://www.refactoring.com. Último acesso em 19/5/2006. [17] Roberts, D. B. “Practical Analysis for Refactoring”. Ph.D. Thesis, Univ. of Illinois at Urbana- Champaign, 1999. [18] Russo, A., Nuseibeh, B., Kramer, J., “Restructuring Requirements Specifications for Managing Inconsistency and Changes: A Case Study”, in Proc. of International Conference on Requirements Engineering, pp. 51-65, 1998. [19] Tichelaar, S. et al. “A Meta-model for Language- Independent Refactoring”, in Proc. of the International Symposium on Principles of Software Evolution (ISPSE 2000). Kanazawa, Japan, November 2000. [20] Tokuda, L., Batory, D., “Evolving object-oriented designs with refactorings”, in Preceedings of 14th IEEE International Conference on Automated Software Engineering, Cocoa Beach, FL , Estados Unidos, p. 174-181, 12 – 15 October, 1999. [21] XRefactoring Home page. Disponível em http://www.xref-tech.com/. Último acesso em 19/5/2006. [22] Wikipedia. Home Page. Disponível em http://pt.wikipedia.org/wiki/Refatora%C3%A7%C3 %A3o. Último acesso em 19/5/2006.
Compartilhar