Detecting Modularity Flaws of Evolving Code: What the History can Reveal? Leandra Mara da Silva, Francisco Dantas, Gustavo Honorato, Alessandro Garcia, Carlos Lucena Departamento de Informática, Pontifícia Universidade Católica do Rio de Janeiro (PUC-Rio), Brasil {lsilva, fneto, ghonorato, afgarcia, lucena}@inf.puc-rio.br Resumo—Anomalias de modularidade (ou code smells) podem prejudicar o reúso e a manutenibilidade do código ou ainda indicar a degradação da arquitetura de um sistema. Por isso, engenheiros de software têm se dedicado em pesquisar mecanismos que auxiliem na detecção dessas anomalias. Estratégias de detecção de anomalias usualmente ignoram informações sobre o histórico das modificações de um sistema. Entretanto, estudos recentes relatam que tais estratégias têm se apresentado contraproducentes. Este artigo propõe e avalia a utilização de estratégias de detecção formadas por métricas que consideram propriedades históricas do código em evolução. Além disso, também é proposta uma ferramenta capaz de dar suporte à abordagem. As estratégias são avaliadas em termos de precisão e revocação para detectar três anomalias clássicas ao longo das 16 versões de dois sistemas. Duas importantes observações são feitas: (i) a utilização de informações sobre a evolução dos módulos pode contribuir com detecções eficazes de anomalias de modularidade; (ii) em ambos os sistemas, estratégias sensíveis à história apresentaram resultados consideravelmente superiores aos de estratégias convencionais. Abstract—Modularity flaws can hamper the reuse and maintainability of code or even indicating the architecture degradation of a system. Therefore, researchers have increasingly investigated new mechanisms to assist the detection of these anomalies. Strategies for detection these flaws usually ignore information about the software change history. However, recent studies report that these strategies have been considered counter-productive. This article proposes and evaluates the use of detection strategies consisting of metrics that consider historic properties of evolving source code. It also proposes tool support for history-sensitive detection of modularity flaws. The strategies are evaluated in terms of precision and recall to detect three classic modularity flaws over 16 versions of two systems. Several observations were made, including: (i) exploiting information about the code evolution can contribute to effective detection of modularity flaws; and (ii) in both systems, history-sensitive strategies presented results superior to conventional strategies. Index Terms—modularity flaws; detection strategies; historysensitive metrics; empirical software engineering; I. I NTRODUÇÃO Em desenvolvimento de sistemas, boas práticas de projeto modular [1][2] devem ser aplicadas visando-se maximizar o reúso e manutenibilidade de sistemas. Entretanto, na prática, nem sempre essa recomendação é respeitada. Sistemas de software sofrem uma série de mudanças de diferentes naturezas, levando à produção de uma série de versões ao longo do histórico dos mesmos. A maioria dessas mudanças são de natureza corretiva ou envolvem incrementos e remoções de funcionalidades. Essas alterações inadvertidamente podem levar à introdução de anomalias de modularidade1 impactando negativamente o reúso e a decomposição modular do sistema [3]. De fato, tendo em vista as restrições de tempo ou inexperiência de programadores, é inevitável que anomalias de modularidade sejam introduzidas em código na medida que novas versões do sistema são geradas [2]. Um exemplo clássico desses problemas são as chamadas God Classes, frequentemente caracterizadas por serem complexas e encapsularem muitas responsabilidades do sistema [1][4][5]. Essa anomalias são indesejáveis devido ao impacto negativo relacionado ao reúso e manutenibilidade do código. Além disso, elas comumente são indicadores de violações básicas de arquitetura. Um caso comum seria uma God Class que, dentre suas várias preocupações, possui código relativo a responsabilidades de diferentes camadas da arquitetura do sistema. Ou ainda que acumula responsabilidades de diferentes interesses do padrão Modelo-Visão-Controle (MVC) [6]. Em casos como estes, a detecção de anomalias em código poderia, adicionalmente, contribuir com a identificação de módulos que potencialmente contribuiriam para a degradação da arquitetura do sistema. Portanto, engenheiros de software têm se dedicado em pesquisar mecanismos que auxiliem na detecção de anomalias de modularidade de código. Métricas [7][8] e estratégias de detecção [9][10] têm sido tradicionalmente exploradas nesse contexto. Um problema central das estratégias de detecção tradicionais [9][10] é que elas apresentam eficácia limitada. Isto é, elas geralmente levam a um número significativo de falsos positivos e falsos negativos [4][5][11]. Um fator limitante é que as métricas utilizadas nessas estratégias tendem a se concentrar exclusivamente em propriedades de versões particulares dos módulos. Ou seja, atualmente, elas não levam em consideração o histórico de mudanças dos módulos para detectar possíveis anomalias. Poucos trabalhos na literatura têm investigado como informações básicas sobre a evolução dos módulos podem: (i) auxiliar na detecção eficaz de anomalias clássicas de modularidade, e (ii) contornar limitações das estratégias baseadas em análises individuais de versões de programas. Existem algumas métricas sensíveis à história propostas recentemente na literatura [4][5], mas nenhum trabalho tem explorado o contexto de estratégias sensíveis à história para identificação 1 Neste artigo, usaremos o termo anomalias de modularidade (ou, simplesmente, anomalias) como sinônimo ao termo em inglês code smells. de anomalias. Em trabalhos mais próximos ao nosso [4][5], métricas de evolução são utilizadas apenas para classificar em prejudiciais ou inofensivos os resultados previamente obtidos pela aplicação de estratégias convencionais [9][10]. Dessa forma, esses trabalhos não possibilitam a detecção dos módulos não detectados pela abordagem convencional. Quanto às ferramentas [12][13][14][15], também não existe nenhuma que permita ao programador definir, de forma flexível, diferentes configurações de estratégias. Elas também não permitem considerar o histórico evolutivo do código das aplicações avaliadas. Um problema ainda maior é que não existe qualquer evidência que estratégias sensíveis à história sejam mais eficazes do que estratégias sensíveis à uma única versão. Tal negligência ocorre até mesmo para detecção de anomalias clássicas de modularidade [2], tais como God Classes. Nesse contexto, algumas contribuições desse artigo são destacadas. Primeiramente é apresentada uma revisão de conceitos relacionados a anomalias de modularidade de código e estratégias de detecção, além de discusões sobre limitações das estratégias convencionais (Seção II). Na Seção III, é proposto um subconjunto de métricas e estratégias de detecção sensíveis à história, além de uma ferramenta de suporte à abordagem. O artigo ainda apresenta uma avaliação sistemática (Seções IV e V) que compara, em termos de precisão e revocação [16], estratégias convencionais e sensíveis à história na detecção de três anomalias clássicas de modularidade [2]: God Class (GC), Divergent Change (DC) e Shotgun Surgery (SS). Esta avaliação é realizada ao longo de 16 versões de dois sistemas de domínio diferentes. Embora, algumas limitações de trabalhos relacionados já tenham sido discutidos nesta introdução, outras comparações são apresentadas ao longo das seções do artigo. Conclusões e trabalhos futuros são apresentados na Seção VI. II. D ETECÇÃO DE A NOMALIAS DE M ODULARIDADE Esta seção apresenta os conceitos fundamentais relacionados a anomalias de modularidade (Seção II-A) e a estratégias convencionais usadas na detecção dessas anomalias (Seção II-B). Exemplos e limitações dessas estratégias também são destacadas nas Seções II-C e II-D, respectivamente. A. Anomalias de Modularidade Martin Fowler e Kent Beck [2] deram uma importante contribuição em tal contexto. Eles catalogaram diversos problemas de código denominados por eles como “code smells”. Tal termo pode ser entendido como uma metáfora normalmente usada para descrever sintomas observados nos módulos que possivelmente prejudicarão o reúso ou manutenibilidade do sistema. Tratam-se de sintomas frequentemente resultantes de indevida modularidade. Por isso, neste artigo, usamos o termo anomalias de modularidade (ou, simplesmente, anomalias) como sinônimo ao termo em inglês code smells. De acordo com Fowler [2], tais anomalias podem trazer impactos bastante negativos ao sistema e a identificação desses problemas indica a necessidade de melhorar a estrutura do código, ou refatorá-lo [2]. Alguns exemplos de anomalias citadas por Fowler são God Class, Divergent Change, e Shotgun Surgery, todas selecionadas no contexto desse estudo (Seção IV-B). Nesse último caso, a má modularização do sistema pode fazer com que a alteração de uma classe possa implicar na necessidade de alterar diversas outras, em um efeito cascata. Outras estruturas prejudiciais ao código também têm sido bastante discutidas na literatura [1][2]. B. Estratégias Convencionais de Detecção Apesar do extensivo uso de métricas, quando consideradas isoladamente, elas fornecem informações de granularidade muito fina e insuficientes para o reconhecimento de anomalias [10]. Para contornar tal limitação, pesquisadores [9][10] propuseram as chamadas estratégias de detecção. Uma estratégia de detecção é uma condição lógica composta por métricas que detecta módulos do código em conformidade com tal condição. Por meio do uso dessas estratégias, o desenvolvedor pode localizar diretamente classes e métodos afetados por uma anomalia de modularidade particular. Isso é possível sem que ele tenha que inferir o problema a partir de um extenso conjunto de valores anormais de métricas. As detecções são realizadas a partir de dois processos denominados filtragem e composição [9]. A filtragem reduz o conjunto inicial dos dados e dá suporte à avaliação de uma métrica, de forma isolada. Por exemplo, na detecção de anomalias presentes em classes, “LOC > 250” define uma filtro absoluto [9] para recuperar todas as classes que possuem mais de 100 linhas; “LOC, TopValues(25%)” define um filtro relativo [9] que recupera 25% das classes com os maiores números de linhas de código. Já o processo de composição tem por objetivo apoiar a interpretação correlacionada dos resultados de diferentes filtros. Isso é feito através da utilização de operadores de composição: “E” ou “OU”. Por exemplo, “(LOC, TopValues(25%)) E (LOC > 100)”, indica a composição dos dois filtros anteriormente mencionados. C. Exemplos de Estratégias Convencionais de Detecção Para detectar GCs, por exemplo, alguns pesquisadores formularam estratégias que visam capturar classes com os seguintes sintomas: (a) acessa vários dados de classes que possuem poucas funcionalidades, (b) possui elevada complexidade e, por fim, (c) apresenta baixa coesão. Para quantificar os sintomas (a), (b) e (c), Marinescu utiliza as seguintes métricas: ATFD (Acesso a Dados Estrangeiros) [9], WMC (Soma das Complexidades dos Métodos) [9] e TCC (Intensidade da Coesão da Classe) [9], respectivamente. A partir dessas métricas, a seguinte estratégia convencional foi definida [9]. ((AT F D > 1) E (W M C, T opV alues(25%)) E (T CC, BottomV alues(25%)) (1) De acordo com a estratégia da Equação 1, serão filtradas: classes que apresentam valores de ATFD maiores que 1; 25% das classes com os maiores valores de WMC; e 25% das classes com os menores valores de TCC. Como o operador de composição é do tipo “E” são consideradas God Classes apenas as classes em conformidade com os três filtros. D. Limitações das Estratégias Convencionais Não é difícil encontrar trabalhos que relatem sobre o considerável número de falsos positivos e negativos gerados por estratégias convencionais de detecção [4][5][11]. Para ilustrar tal limitação, avaliaremos o resultado de detecção da estratégia de Marinescu, apresentada pela Equação 1. Tratase de uma estratégia convencional e que, sendo assim, não considera a análise do histórico das classes para realizar as detecções. De fato, no estado da arte, estratégias de detecção [9][10] apresentam regras com tais características, agnósticas ao histórico, independentemente da anomalia a ser detectada. A Figura 1 ilustra a classe ImageAccessor como um exemplo de GC presente em uma aplicação chamada Mobile Media [17]. Tal classe possui mais de 250 linhas de código e foi projetada para prover as funcionalidades de persistência de todos os objetos de domínio da aplicação. Isto viola a idéia que uma classe deveria capturar uma e somente uma abstração. Através de análise minuciosa do código também é possível observar o entrelaçamento de diferentes responsabilidades na classe. Na Figura 1, os dois diferentes tons de cinza ilustram o entrelaçamento de código relativo a operações de persistência dos objetos de negócio: ImageData e AlbumData. Figura 1. Entrelaçamento de responsabilidades e valores de métricas convencionais da God Class ImageAccessor ImageAccessor apresenta os seguintes valores de métricas: ATFD = 2, WMC = 32 e TCC = 28 (Figura 1). Aplicando a estratégia representada pela Expressão 1, ela não é detectada como GC pois não possui um dos menores valores de coesão do sistema. O uso de filtros relativos, como o utilizado para avaliar TCC, contribui frequentemente com a ocorrência de falsos positivos e negativos. Isso porque a avaliação de um determinado módulo fica muito dependente dos resultados das métricas dos demais módulos. Além disso, a inclusão ou remoção de outros módulos acaba interferindo diretamente no resultado do módulo avaliado. Uma outra estratégia convencional [10] foi testada para detectar essa mesma anomalia. Entretanto, novamente o resultado foi contraproducente. Uma possível limitação encontrada nessas estratégias é que as propriedades de evolução do sistema não são consideradas. Por exemplo, ImageAccessor talvez não possui um dos menores valores de coesão, mas talvez fosse importante observar que sua coesão veio decrescendo gradativamente ao longo de sua história. Informações sensíveis à história como essa poderiam fornecer algum suporte para auxiliar nas detecções. Entretanto, embora o desenvolvimento de software seja cada vez mais incremental, estratégias de detecção atuais não consideram a evolução das características dos módulos. III. R ECURSOS DE D ETECÇÃO S ENSÍVEIS À H ISTÓRIA Esta seção tem por objetivo apresentar as métricas (Seção III-A), estratégias de detecção sensíveis à história (Seção III-B) e a ferramenta de suporte (Seção III-C) propostas no contexto dessa pesquisa. A. Métricas Sensíveis à História Com o objetivo de contornar as limitações apresentadas na seção anterior e de avaliar as influências de se utilizar informações sobre a evolução em estratégias de detecção, um conjunto de métricas sensíveis à história foi definido. Enquanto métricas convencionais ou orientadas a uma única versão [7][8] avaliam uma “fotografia” da versão atual do código, métricas sensíveis à história (SHs) [4][18] consideram a avaliação das características dos módulos ao longo do seu histórico. Dessa forma, elas são capazes de fornecer indicadores sobre a evolução de propriedades do código, como complexidade, acoplamento, coesão ou outras. Muitas são as métricas sensíveis à história definidas no contexto de nossos estudos. Entretanto, apresentamos nessa seção apenas um subconjunto de métricas de maior relevância nesse trabalho. As métricas apresentadas na Tabela I podem ser utilizadas para avaliar módulos de diferentes granularidades, sejam pacotes, classes ou métodos. Em conformidade com o uso da abordagem GQM (Goal-Question-Metric) [19], a primeira coluna da tabela apresenta a pergunta a ser respondida pelo subconjunto de métricas apresentado. Além disso, a evolução de diferentes propriedades de código pode ser considerada por tais métricas, apesar de na segunda coluna da tabela apenas a propriedade LOC (linhas de código) ter sido usada como exemplo. A terceira coluna da Tabela I apresenta a definição formal das métricas sensíveis à história e o raciocínio utilizado na implementação de cada uma na ferramenta descrita na Seção III-C. A maioria das métricas SHs são baseadas na extensão de métricas que consideram a medição de uma única versão do sistema, ou seja, métricas não sensíveis à história (NSH). Nesse caso, tais métricas SHs seguem uma mesma regra de formação na definição de suas siglas. Essa regra é composta por dois elementos: prefixo SH + sigla de métrica NSH. O elemento “prefixo SH” representa de que forma uma propriedade P será avaliada no contexto sensível a história. Por exemplo, a propriedade complexidade pode ser avaliada (i) contabilizando-se a quantidade de vezes que tal medida cresceu ao longo da história, (ii) verificando-se a quantidade de vezes que tal propriedade permaneceu estável, ou outras formas similares. O segundo elemento “sigla de métrica NSH” representa a sigla da métrica convencional (ou não sensível à história) selecionada para avaliar essa propriedade P. Note que as cinco primeiras métricas apresentadas na Tabela I, seguem tal lei de formação pois tomam como base a evolução de métricas convencionais. Nos exemplos utilizamos a métrica Tabela I E XEMPLOS DE M ÉTRICAS S ENSÍVEIS À H ISTÓRIA Pergunta GQM Qual o valor de uma dada propriedade1 na versão anterior à versão atual de um módulo? Exemplo de Métrica SH usando LOC1 1) pLOC (Previous LOC) Exemplo de formulação utilizando linhas de código (LOC) pLOCv = LOCv−1 { 0, se (LOCv < LOCv−1 ); LOCv − LOCv−1 × 100, caso contrário. LOCv−1 rpiLOCv = Qual o aumento percentual de uma propriedade da versão anterior para a versão atual de um módulo? 2) rpiLOC (Recent Percentage Increase of LOC) Qual o decaimento percentual de uma propridade em relação ao seu valor na primeira versão do módulo? 3) rpdLOC (Recent Percentage Decrease of LOC) rpdLOCv = Qual a variação média de uma propriedade ao longo da evolução de um módulo? 4) rdocLOC (Relative Difference of Overall Change of LOC) rdocLOCv = Qual a quantidade relativa de vezes que uma determinada propriedade cresceu ao longo da evolução de um módulo 5) rniLOC (Relative Number Of Increase of LOC) rniLOCv = Em quantas alterações de versão do sistema um determinado módulo se fez presente? Qual a “idade” de um determinado módulo no sistema? 6) TL (Time Life) T Lv = ( { 0, se (LOCv > LOCv−1 ); LOCv − LOCv−1 × 100, caso contrário. LOCv−1 ∑v i=2 ∑v ∑v i=1 i=2 LOCv − LOCv−1 T Lv Xi onde Xi = T Lv Xi ) − 1 onde Xi = { { 0, 1, 0, 1, se o LOC não cresceu de vi−1 para vi se o LOC cresceu de vi−1 para vi se o módulo está presente na versão i; se o módulo não está presente na versão i 1 Linhas de Código (LOC) foi utilizada na tabela como um exemplo de propriedade a ser inspecionada ao longo da evolução. Tais métricas sensíveis à história podem ser aplicadas para avaliar a evolução de qualquer outra propriedade, como coesão, acoplamento, etc. LOC. Já a sexta métrica da tabela, a TL (ou tempo de vida), não segue o padrão mencionado, pois trata-se de uma métrica sensível à história independente de qualquer métrica convencional. B. Estratégias de Detecção Sensíveis à História Nesse trabalho chamamos de estratégias sensíveis à história, estratégias de detecção que levam em consideração a evolução das propriedades dos módulos para “diagnosticar” anomalias de modularidade. Dessa forma, estratégias sensíveis à história devem possuir, necessariamente, métricas sensíveis à história (Seção III-A) em sua composição. A estratégia sensível a uma única versão, a qual chamamos de estratégias convencionais, pode perder informações essenciais sobre os sintomas dos módulos ao longo do histórico dos sistemas. Por exemplo, crescimento em linhas de código, número de alterações e assim por diante. Alguns pesquisadores [5][20] acreditam que avaliar anomalias de modularidade considerando o passado dos módulos possa contribuir para melhorar a eficácia das detecções atuais. Por exemplo uma classe que é frequentemente alterada ou que possui tamanho e complexidade crescentes não poderia indicar que ela possui algum problema de modularidade? Ou ainda, a constatação de classes estáveis que sofrem poucas variações de suas propriedades, não poderia indicar um projeto bem modularizado? Destacamos que diversas estratégias SHs poderiam ser configuradas e testadas no sentido de melhorar a eficácia relacionada à detecção de anomalias. Entretanto, até o momento, não existiam ferramentas para dar suporte à aplicação ED-SH1 - God Class: S E complexidade é grande ou tamanho e complexidade já eram grandes em passado recente e tais propriedades continuam crescendo ENTÃO POSSÍVEL God Class ((W M C > η) OU ((pLOC > α) E (pW M C > β) E (rpiLOC > γ) E (rpiW M C > δ))) (2) ................................................................... ED-SH2 - Divergent Change: S E a classe depende de muitas outras classes de muitos distintos pacotes e além disso é grande e, ao longo da história, a dependência a outros pacotes foi crescente ENTÃO POSSÍVEL Divergent Change ((DD > α) E (N OED > β) E ((LOC > γ) OU (rniN OED > δ))) (3) ................................................................... ED-SH3 - Shotgun Surgery S E alterações na classe potencialmente afetam muitos métodos e muitas outras classes e muitas são as classes que herdam direta ou indiretamente dessa classe ENTÃO POSSÍVEL Shotgun Surgery ((CM > η E ChC > θ) OU (rniN OCC > ε)) (4) e teste de estratégias que considerassem a evolução do código. A ferramenta a ser apresentada na Seção III-C é capaz de dar suporte a essas diferentes possibilidades de configurações de estratégias. Com base nas métricas SHs apresentadas na Seção III-A, podemos propor três estratégias a serem testadas na detecção das anomalias citadas na Seção II-A. Essas estratégias são representadas pelas Equações 2, 3 e 4. Os limites associados às métricas foram representados por letras gregas pois estudos empíricos ainda precisam ser realizados para que se possam determinar tais valores. Além disso, a escolha desses valores depende também das características do sistema a ser avaliado. Como usualmente ocorre, caberá ao desenvolvedor ou avaliador de código especificar quais valores serão utilizados para parametrizar as estratégias. C. A Ferramenta Hist-Inspect A ferramenta Hist-Inspect visa contornar limitações observadas nas ferramentas de suporte a estratégias de detecção. Percebe-se que, embora algumas ferramentas [12][13][14][15] tenham sido propostas para suportar estratégias de detecção, nenhuma delas dá suporte a métricas ou estratégias de detecção sensíveis à história. Além disso, a maior parte não permite que o usuário do sistema possa adicionar ou alterar estratégias. Naquelas em que alguma configuração é possível, o usuário não possui tanta flexibilidade para criar estratégias quanto lhe poderia ser dada com especificações através de linguagens específicas de domínio (DSLs) [21]. Nesse contexto, através das ferramentas de detecção atuais, torna-se impossível avaliar os efeitos da utilização de informações sensíveis à história na detecção de anomalias de modularidade. Em ferramentas clássicas como o Together [12] e a inCode [13], os algoritmos de detecção são definidos em âmbito de código por desenvolvedores, ao invés de poderem ser especificados em alto nível por especialistas no domínio de detecção e avaliação de código. Outras ferramentas como a iPlasma [14] e a inFusion [15] até disponibilizam a inclusão e alteração de estratégias em alto nível, porém com algumas limitações, como: (i) as novas estratégias não podem ser salvas para utilizações futuras, e (ii) as customizações são limitadas pelo uso de elementos e operações disponíveis em uma interface de configuração. Por exemplo, não se consegue especificar uma estratégia que contenha a expressão m1 /m2 ou a expressão m1 > m2 , onde m1 e m2 representam métricas. Resumidamente, apresentamos, a seguir algumas características da Hist-Inspect. Utilização de Repositório de Métricas Convencionais (RMCs): como descrito na Seção III-A, as métricas sensíveis à história, em sua grande maioria, são calculadas avaliando-se a evolução de propriedades capturadas por métricas convencionais. Na versão atual da ferramenta, os resultados das métricas convencionais são obtidos de arquivos XML de entrada. À princípio, optamos por utilizar os resultados gerados pela Together [12], por se tratar de uma ferramenta bem conhecida e aceita, tanto na indústria quanto na academia. Para cada versão do sistema a ser avaliado é recebido como entrada um arquivo de extensão .mtbl2 . Esse arquivo é chamado por nós de “Repositório de Métricas Convencionais vx” ou “RMC vx”, onde x representa a versão do sistema em que as métricas convencionais foram aplicadas. Métricas, Gráficos e Estratégias Sensíveis à História: métricas, gráficos e estratégias de detecção sensíveis à história podem suportar a avaliação de módulos em níveis distintos de granularidade (métodos, classes ou pacotes). Isso é possível 2 Extenção do arquivo gerado pelo Together com métricas convencionais. pois a evolução é avaliada com base em métricas convencionais disponibilizadas pelos RMCs e diferentes granularidades dessas métricas são disponibilizadas nesses repositórios. A ferramenta também é capaz de suportar a especificação e aplicação tanto de estratégias sensíveis à história quanto a de estratégias convencionais. Tal recurso traz grande contribuição a pesquisas que avaliam a eficácia de diferentes estratégias. Especificação de Estratégias através de DSL Interna: a ferramenta proposta utiliza uma linguagem específica de domínio (DSL) [21] para possibitar a especificação declarativa de estratégias de detecção. Isso permite ao programador definir, de forma flexível, estratégias com diferentes configurações de métricas, valores limites e operadores de composição. Trata-se de uma DSL interna [22] através da qual pudemos reutilizar todos os elementos sintáticos e também o interpretador da linguagem base utilizada, o JavaScript. Tais reutilizações trouxeram como principal vantagem a rápida implementação da funcionalidade associada nos desobrigando da necessidade de especificar, por exemplo, uma gramática (BNF) ou outros elementos necessários para a definição de linguagens. A Equação 5 mostra um exemplo de especificação usando a DSL. (CM > 7 && ChC > 7) || (rniNOCC > 0) (5) Note que especificar uma estratégia de detecção na HistInspect é praticamente equivalente à definição formal de alto nível (Equação 4). As métricas utilizadas são entendidas como simples variáveis pelo interpretador de JavaScript. Quanto aos elementos de especificação, todos os recursos da limguagem base, como operadores lógicos (OU e E, representados respectivamente como “||” e “&&”) e operadores matemáticos (como “==”, “>”, “<”, “≥”), dentre outros, são automaticamente disponibilizadas para serem utilizados. As estratégias, atualmente, são fornecidas através de um arquivo de entrada denominado Catálogo de Regras. As figuras 2 e 3 apresentam respectivamente uma tela de apresentação de métricas SHs e um relatório HTML com detecções de anomalias na HistInspect. Por restrições de espaço, outras telas e outros detalhes da ferramenta são disponibilizados no sítio dessa pesquisa [23]. Figura 2. Apresentação de métricas sensíveis à história. Figura 3. Relatório HTML com resultado de detecções. IV. AVALIAÇÃO : P ROCEDIMENTOS Essa seção descreve os procedimentos de avaliação de estratégias sensíveis à história na detecção de anomalias de modularidade. A partir desta avaliação exploratória não é nosso objetivo generalizar os resultados obtidos, mas apenas avaliar a eficácia das estratégias em versões diversas de dois sistemas. Os critérios de seleção desses sistemas bem como algumas de suas características são apresentadas na Seção IV-A. As anomalias selecionadas para esse estudo são destacadas na Seção IV-B. A Seção IV-C apresenta o processo de obtenção das anomalias reais nos sistemas selecionados. Na Seção IV-D, destacamos os pressupostos dessa avaliação através das hipóteses a serem testadas, bem como as medidas utilizadas para avaliação do conceito de eficácia (Seção IV-E). Todos os artefatos desta avaliação estão disponíveis em [23]. A. Critérios de Seleção dos Sistemas A elaboração de oráculos ou de listas de referência (Seção IV-C) confiáveis é altamente dependende da disponibilização de desenvolvedores ou projetistas que conheçam o código das aplicações alvo. Percebemos que a maioria das pesquisas [24][20] que avaliam a detecção de um elevado número de sistemas e de versões se rende a tomar as detecções de estratégias convencionais como verdadeiras. Entretanto, tais pesquisas possibilitam muito fortemente a propagação de erros devido aos falsos positivos e negativos detectados. Para evitar tal risco, optamos por utilizar um número reduzido de sistemas e de versões, mas ter a vantagem de ter como referência anomalias detectadas manualmente por especialistas. Com base nos critérios discutidos acima, selecionamos dois sistemas de pequeno e médio porte: Mobile Media (MM) [17] e Health Watcher (HW) [25]. O primeiro, trata-se da implementação de uma linha de produtos [26] para manipulação de fotos, músicas e vídeos em aparelhos celulares. O segundo é um sistema de informação de tecnologia Web cuja principal funcionalidade é o registro de queixas relacionadas à qualidade de serviços de estabelecimentos públicos. A seleção desses sistemas foi uma decisão estratégica baseada principalmente nas semelhanças e diferenças existentes entre eles e que foram consideradas igualmente importantes para essa avaliação. Tais semelhanças e diferenças são descritas a seguir. Semelhanças importantes: 1) Para ambos os sistemas seria possível acessar projetistas que poderiam identificar manualmente e/ou confirmar as anomalias reais das aplicações. Isso tornaria possível a avaliação confiável dos resultados em relação a opinião desses especialistas. 2) Ambos os sistemas foram desenvolvidos com a preocupação de atender requisitos de modularidade de código. Tal característica torna a detecção de anomalias nesses sistemas longe de ser trivial. Esta particularidade foi considerada interessante pois poderia contribuir para explorarmos o apoio a detecções não óbvias e que frequentemente passariam despercebidas por equipes de desenvolvimento ou por estratégias convencionais. Diferenças importantes: 1) Tais aplicações pertencem a diferentes domínios, além de utilizarem diferentes tecnologias de implementação. Tal fato contribui para que a possível obtenção de resultados comuns entre as aplicações não seja induzida pela utilização de sistemas de elevada similaridade, de mesmo domínio ou mesma tecnologia. 2) Esses sistemas apresentam cenários de evolução bastante diferenciados. No MM, cada versão se diferencia da anterior pela adição de novas funcionalidades. Enquanto no HW, as diferenças relativas às evoluções são geralmente resultantes de sucessivas reestruturações. Nesse estudo, foram consideradas 6 versões do Mobile Media (v2-v7) e 10 versões do Health Watcher (v1-v10). A Tabela II apresenta, de forma resumida, algumas características quantitativas dessas aplicações. Nela, é possível observar que, apesar de termos um maior número de versões no Health Watcher, ele possui um crescimento médio do número de classes (NOC) menor que o observado no Mobile Media. Além disso, o crescimento médio em linhas de código (LOC) do MM é muito mais expressivo que o do HW (238.75 contra 22.98) – o que faz com que consideremos o primeiro sistema mais instável que o segundo. Tal comportamento provavelmente é influenciado pela especificidade de evolução de cada aplicação. Confirmando a informação sobre a modularidade das aplicações (item 2 de Semelhanças Importantes), a última linha da tabela destaca médias de anomalias consideravelmente baixas para ambos os sistemas. B. Anomalias Selecionadas As anomalias a serem detectadas no contexto dessa avaliação são: God Class (GC), Shotgun Surgery (SS) e Divergent Change [1][2]. GC foi escolhida pois, segundo algumas pesquisas, classes com tal problema costumam ser bastante instáveis e propensas a erros. Dessa forma, acreditase que análises sensíveis à história possam contribuir com tais detecções [4]. Além disso, essa anomalia possui uma estratégia convencional para sua detecção - o que contribui Tabela II P RINCIPAIS CARACTERÍSTICAS DAS APLICAÇÕES DO Tipo de Aplicação Ling. de Programação Nº de Versões Disponíveis Nº de Versões Selecionadas LOC1 em v1 LOC em vn Cresc. Médio de LOC NOC2 em v1 NOC em vn Cresc. Médio de NOC Média de GC3 (v1 à v7 ) 1 LOC: 2 NOC: Mobile Media Linha de Produto Java 8 6 760 2670 1910/8 = 238.75 16 51 45/8 = 5.6 15/7 = 2.5 ESTUDO Health Watcher Sistema Web Java 10 10 5295 7593 2298/10 = 22.98 88 135 47/10 = 4.7 32/10 = 3.2 Número de linhas de código, desconsiderando brancos e comentários; Número de Classes; 3 GC: God Classes com possíveis comparações com estratégias da literatura. Já SS e DC foram escolhidas, pois diversas pesquisas sobre mecanismos de avaliação de modularidade contemplam tais anomalias. Essas pesquisas consideram para tal detecção tanto recursos visuais [27] quanto estratégias formadas por outros tipos de métricas, por exemplo sensíveis a interesses [11]. Tal fato possibilita comparações futuras com essas outras abordagens de detecção. Além disso, no caso da anomalia DC, não existe na literatura nenhuma estratégia convencional para apoiar tal detecção. Tal fato nos possibilita verificar se estratégias SHs podem trazer tal contribuição. C. Listas de Referência ou Oráculos Para obtenção das anomalias reais dos sistemas (Seção IV-A) foi solicitada a contribuição de dois especialistas de cada um dos sistemas. Com a apresentação das definições das anomalias, solicitamos que eles: (i) apresentassem uma lista das entidades que eles julgavam infectadas pela anomalia, e (ii) destacassem a confiabilidade de cada detecção. Esse critério seria utilizado caso fosse necessária alguma reunião de consenso. É sabido que, devido a subjetividade encontrada nas definições das anomalias, a conclusão sobre a existência ou não de uma anomalia pode, frequentemente, gerar controvérsias. Como cada sistema foi avaliado por mais de um especialista, de forma não surpreendente, as entidades detectadas por um não foram exatamente as consideradas pelo outro. Para contornar tal situação, foi realizado uma reunião entre os mesmos para que cada um explicasse seu ponto de vista e então se chegasse a uma consenso. O resultado das discussões foi considerado como a opinião de um terceiro especialista, indicando uma decisão comum. Dessa forma, apenas as entidades selecionadas por pelo menos dois especialistas é que passaram a fazer parte do oráculo considerado oficial. D. Hipóteses Nesse trabalho, definimos duas hipóteses relacionadas a eficácia de estratégias sensíveis à história. O método adotado para avaliação da eficácia é apresentado na Seção IV-E. Para cada hipótese Hx definida é apresentada separadamente a hipótese nula (Hx-0) e a alternativa (Hx-1), onde x representa o respectivo número da hipótese. A primeira hipótese objetiva avaliar estratégias SHs de forma isolada, sem comparar seus resultados com os de estratégias convencionais. Já a segunda hipótese direciona uma avaliação relativa, guiada principalmente pela comparação dos resultados de estratégias sensíveis à história com os de estratégias convencionais. Essas hipóteses são definidas a seguir. Hipótese 1 (H1) • H1-0: Estratégias sensíveis à história podem contribuir com detecções eficazes de anomalias de modularidade. • H1-1: Estratégias sensíveis à história não podem contribuir com detecções eficazes de anomalias de modularidade. Hipótese 2 (H2) • H2-0: Estratégias sensíveis à história apresentam melhor eficácia que estratégias convencionais. • H2-1: Estratégias sensíveis à história não apresentam melhor eficácia que estratégias convencionais. E. Dados para Avaliação de Eficácia das Estratégias A avaliação da eficácia no estudo foi suportada pela análise das medidas de revocação e precisão. Além disso, outras variáveis a serem disponibilizadas para análises dos dados são: (i) número de acertos ou verdadeiros positivos, (ii) número de falsos positivos e (iii) número de falsos negativos. Um acerto (VP) ocorre quando a estratégia avaliada identifica uma entidade que também está presente na lista de referência. Um falso positivo (FP) ocorre quando a entidade detectada não se encontra na lista de detecção previamente elaborada. Um falso negativo (FN) ocorre quando uma entidade está na lista de referência mas não conseguiu ser detectada pela estratégia avaliada. É a partir dessas variáveis que as medidas de revocação e precisão são calculadas. A revocação representa o percentual de acertos em relação as entidades presentes na lista de referência. Enquanto que a precisão representa o percentual de acertos em relação as entidades detectadas. Os cálculos são realizados de acordo com as seguintes fórmulas: VP VP Precisão = VP + FN VP + FP F. Estratégias e Valores Limites Considerados Revocação = Para possibilitar discussões sobre as hipótese H1 e H2 as estratégias SHs apresentadas na Seção III-B foram aplicadas nos sistemas selecionados (Seção IV-A) e avaliadas em termos de precisão e revocação (IV-E). De forma independente, também foram aplicadas as estratégias convencionais definidas por Marinescu [10] para detectar as mesmas anomalias. Para aplicação das estratégias de Marinescu foram utilizados três mecanismos de forma que um pudesse validar o resultado dos outros. Esses mecanismos foram: (1) utilização da ferramenta proposta Hist-Inspect (Seção III-C); (2) aplicação manual das estratégias a partir dos resultados de métricas gerados pela ferramenta Together [12]; e (3) utilização da ferramenta iPlasma [14], proposta pelo grupo de pesquisa de Marinescu. Cada estratégia sensível à história foi aplicada nos sistemas selecionados em dois casos. No caso1, as estratégias foram aplicada em cada versão, sem considerar o mapeamento de histórico das classes que sofreram refatorações de tipo “rename”. Ou seja, uma classe renomeada passava a ser considerada uma nova classe, perdendo parte da sua história. No caso2, as mesmas estratégias foram reaplicadas assumindo que as entidades renomeadas ainda permeneciam com seus nomes originais. Refatorações desse tipo foram observadas apenas na versão 7 do MM e na versão 2 no HW. Nosso interesse em testar o caso2 era o de avaliar os efeitos da abordagem sensível à história caso ela fosse estendida de forma a conseguir detectar a ocorrência de refatorações desse tipo. Para isso, as classes renomeadas foram acessadas e refatoradas para que recebesses seus nomes originais. Os limites utilizados nas estratégias sensíveis à história foram testados de acordo com sugestões dos especialistas desses sistemas. Tabela III D ETECÇÃO S ENSÍVEL À H ISTÓRIA A. Primeiro Sistema: Mobile Media Eficácia de Detecções Sensíveis à História (H1): a Tabela III apresenta os dados de avaliação referentes à detecção de todas as anomalias consideradas, em todas as versões do Mobile Media. Como pode ser observado nessa tabela, em todas as versões avaliadas a menor precisão e revocação ao longo das versões foi de 50%. Tanto na detecção de GCs quanto na detecção de DCs foi possível detectar 100% das anomalias em pelo menos duas versões distintas. Tal resultado ocorreu em v5 e v6 no caso da detecção de GCs e de v2 à v4 no caso de DCs. Outra observação é que nessas mesmas versões, em que o número de acertos de GCs e DCs foi máximo, também não houve a detecção de nenhum falso positivo, o que também repercurtiu em precisão de 100%. Pudemos constatar que apenas na versão 7 caso1 (Seção IV-F) referente à detecção de GCs não foi possível identificar uma anomalia sequer. Entretanto, existe uma justificativa razoável para tal fato. Tal resultado em v7 pode ser discutido analisando-se comparativamente os resultados da estratégia pra GC nos casos 1 e 2, esse último entre parênteses. O caso 2 considera a aplicação da estratégia como se a avaliação fosse capaz de identificar refatorações do tipo “rename”. Em v7, por ser a última versão e por apresentar o maior histórico dentre as versões, era esperado que fosse obtido um dos melhores percentuais de M OBILE M EDIA God Class (GC) v3 v4 v5 1 1 1 0 0 0 1 1 0 50% 50% 100% 100% 100% 100% Acertos Falsos Positivos Falsos Negativos Revocação Precisão v2 1 0 1 50% 100% Acertos Falsos Positivos Falsos Negativos Revocação Precisão Divergent Change (DC) v2 v3 v4 v5 2 2 2 2 0 0 0 0 0 0 0 1 100% 100% 100% 67% 100% 100% 100% 100% Acertos Falsos Positivos Falsos Negativos Revocação Precisão v21 n/a 0 0 n/a n/a V. A PRESENTAÇÃO DOS R ESULTADOS E D ISCUSSÕES Nessa seção, apresentaremos os resultados de avaliação das estratégias em duas etapas. Primeiro, reportaremos as medidas definidas na Seção IV-E resultantes da aplicação das estratégias sensíveis à história. Em seguida, reportaremos os resultados médios de precisão e revocação relativos à aplicação das estratégias SHs e convencionais. As medidas de precisão e revocação versão a versão das estratégias SHs serão apresentadas apenas para o primeiro sistema. Por limitações de espaço, no segundo sistema discutiremos apenas as médias de precisão e revocação referentes à detecção de GCs. Entretanto, demais dados da avaliação em tal sistema também estão disponíveis em [23]. Em todas as tabelas à seguir as medidas de precisão e revocação foram apresentadas em sua forma percentual. Quando houve a impossibilidade de efetuar o cálculo de uma dessas medidas devido a divisões por zero, um traço foi utilizado para simbolizar a situação. NO Shotgun Surgery (SS) v31 v41 v5 n/a n/a 2 0 0 1 0 0 1 n/a n/a 67% n/a n/a 67% v6 2 0 0 100% 100% v71 0 (1) 0 (0) 2 (1) 0% (50%) - (100%) v6 2 1 1 67% 67% v71 2 (2) 2 (1) 2 (2) 50% (50%) 50% (67%) v6 2 1 1 67% 67% v72 3 (4) 3 (4) 1 (0) 75%(100%) 50% (50%) 1 n/a (não aplicável): não existem anomalias do tipo SS a serem detectadas nessas versões. 2 Em v7, os resultados entre parênteses são referentes à aplicação da estratégia no caso2 (Seção IV-F). acerto. Entretanto, surpreendentemente, nessa versão obteve-se o pior resultado como pode ser observado. A justificativa para tal fato é que as classes detectadas corretamente em versões anteriores sofreram renomeação em v7. Ao considerarmos o caso2, pudemos observar que uma dentre as duas GCs existentes em v7 passou a ser detectada. Tal fato possibilitou a obtenção de 100% de precisão na detecção de GCs em todas as versões. A estratégia SH só não conseguiu detectar a outra anomalia existente pois essa apresentou uma redução de complexidade de aproximadamente 100 linhas de código. Isso fez com que a estratégia SH tivesse considerado a eliminação da anomalia detectada na versão anterior. Esse fato foi o único que impossibilitou a obtenção de uma revocação de 100%, o que já tinha sido obtido na precisão. Elevados valores de precisão e revocação também puderam ser observadas nas detecções de DC e SS. Outras observações importantes de serem feitas é que no caso de DC ainda nem existe na literatura relacionada uma estratégia convencional proposta para tal detectar tal anomalia. Contudo, a estratégia sensível à história avaliada para DC apresentou-se bastante eficiente. Como relatado anteriormente, foram obtidos valores de 100% de precisão e revocação na metade das versões avaliadas (v2-v4). Além disso, no que diz respeito à detecção de SS, segundo inspeção manual nem haveria a necessidade de avaliar a estratégia correspondente nas versões iniciais do MM, pois não existia tal anomalia nessas versões. Dessa forma, não seria possível avaliar o número de entidades detectadas como anômalas corretamente nem de efetuar os cálculos de precisão e revocação. Apesar disso, a estratégia foi aplicada e, de fato, ela não considerou a detecção de nenhuma anomalia desse tipo entre v2 e v4, passando a identificá-la apenas a partir da versão em que se era esperado iniciar a aplicação das estratégias. Nesses casos, de v3 à v7, também foi observado que, considerando a possibilidade de mapear o histórico de entidades renomeadas (caso 2, entre parênteses), foi possível a detecção de 100% das anomalias desse tipo. No caso em que o mapeamento de renomeações não foi considerado também foi possível obter uma revocação satisfatória de 75%. Se nos basearmos apenas nos resultados obtidos na avaliação com o Mobile Media podemos dizer que são apresentadas evidências iniciais que suportam a hipótese nula de H1 (H10). Ou seja: “Estratégias sensíveis à história podem contribuir com detecções eficazes de anomalias de modularidade”. Todos esses dados nos trazem fortes indícios de que estratégias sensíveis à história poderiam ser mais exploradas na identificação de anomalias de código. Estratégias Sensíveis à História vs. Estratégias Convencionais (H2): a Tabela IV apresenta os valores médios de precisão e revocação da aplicação das estratégias convencionais e sensíveis à história nas versões do Mobile Media. Como podemos observar, não há possibilidade de efetuar uma avaliação comparativa sobre os resultados de detecção da anomalia DC. Isso ocorre pois, como já mencionamos na Seção IV-B, não foi proposto nem em estudos mais antigos [9] nem em mais recentes [10] uma estratégia convencional para detectar tal anomalia. Já nos casos de GC e SS, algumas observações podem ser feitas. Na avaliação do Mobile Media, claramente a estratégia convencional não apresentou-se efetiva para detectar GCs. Analisando separadamente as versões, cujos dados não foram apresentados por restrições de espaço, percebemos que tal estratégia detectou 50% das anomalias em apenas duas das seis versões consideradas. Em todas as demais não houve nenhum acerto. Nesse caso, como mostra a Tabela IV, os valores médios de precisão e revocação foram inferiores a 40%. A revocação apresentou o valor médio de 16.6% enquanto a precisão média o valor de 33%. Tabela IV M ÉDIAS DOS RESULTADOS DAS ESTRATÉGIAS NO M OBILE M EDIA Estrat. Sensíveis à História Estrat. Convencionais God Classes (GC) Avg. Revocação 66.6% 16.6% Avg. Precisão 100% 33% Divergent Change (DC) Avg. Revocação 80.6% n/a1 Avg. Precisão 89% n/a1 Shotgun Surgery (SS) Avg. Revocação 78% 38.6% Avg. Precisão 61.3% 46.6% 1 Não existe na literatura estratégias convencionais para detectar DC. Em contrapartida, utilizando uma estratégia com informações sensíveis à história obteve-se uma média de revocação satisfatória de 66%, com uma precisão média de 100%. Mesmo no caso da anomalia SS, foi possível uma revocação média de 78% resultante de estratégia sensível à história contra 38.6% resultante de estratégia convencional. Na análise de precisão ainda assim a estratégia sensível à história se sobressai à convencional com uma valor médio de 61.3% contra o valor de 46.6%. Dessa forma, de acordo com os dados do Mobile Media, também é possível dispor de evidências que suportam H2-1. Ou seja, é possível que estratégias SHs sejam mais eficazes que estratéias sensíveis à histórica na detecção de anomalias de modularidade. Estratégias SHs apresentaram melhores resultados em todas as anomalias selecionadas, não apenas nos resultados médios de precisão e revocação mas também em cada versão, de forma individual. B. Segundo Sistema: Health Watcher Eficácia de Detecções Sensíveis à História (H1): a Tabela V apresenta os dados de avaliação referentes à detecção da anomalia GC, em todas as versões do Health Watcher. Como mencionamos, por questões de espaço, disponibilizamos os dados das demais anomalias no sítio desta pesquisa [23]. Enquanto no Mobile Media as estratégias sensíveis à história apresentaram-se bastante eficazes em todas as anomalias avaliadas, no Health Watcher elas não apresentaram-se tão eficazes. Como pode ser observado nessa tabela, a estratégia SH possibilitou apenas a detecção de anomalias em 3 das 10 versões avaliadas. Nessas versões, v4, v7 e v9, todos os valores de revocação foram abaixo de 50%. Um ponto positivo é que nessas três versões a precisão foi de 100%. Outro avaliação positiva é que, execeto em v7, em todas as demais versões, apesar de não terem ocorridos acertos ou verdadeiros positivos, também não foram detectados nenhum falso positivo. Apesar disso, o resultado não foi considerado satisfatório, devido ao baixos valores de precisão e revocação. Como mencionamos na Seção IV-A, algumas diferenças existentes entre o Mobile Media e Health Watcher foram consideradas importantes para essa avaliação, justamente para evitar replicações forçadas de bons ou maus resultados. Ou ainda para não haver o favorecimento de uma ou de outra abordagem. Era consideralvelmente importante para essa pesquisa avaliar a eficácia das estratégias em diferentes contextos de evolução. Evidências como as apresentadas através do estudo com o Health Watcher nos fazem suspeitar que provavelmente em sistemas com evolução pouco expressiva, isto é, em que as versões são geradas principalmente à partir de refatorações, as estratégias sensíveis à história podem não apresentar bons resultados. De fato, os excelentes resultados de detecções sensíveis à história observados no primeiro sistema não foram igualmente constatados no segundo. Estratégias Sensíveis à História vs. Estratégias Convencionais (H2): Apesar da estratégia sensível à história não ter se apresentado muito eficaz na avaliação com o HW, pudemos observar que, ainda assim, tal estratégia apresentou-se mais eficaz que a estratégia convencional. A Tabela IV apresenta os valores médios de precisão e revocação dessas estratégias nas versões do Health Watcher. Enquanto a estratégia SH detectou falso positivo apenas em v10, com a aplicação da estratégia convencional falsos positivos foram detectados em todas as versões. Além disso, a estratégia convencional não conseguiu obter nenhum acerto em nenhuma das 10 versões avaliadas, enquanto a estratégia SH possibilitou acertos em v4, v7 e v9. Nesse caso, apesar do resultado não satisfatório da estratégia SH, pudemos observar uma revocação média de 10% e uma precisão média de 33%. Enquanto a estratégia convencional apresentou médias de 0% de precisão e de revocação, como mostra a Tabela IV. Tal fato, faz com que nesse sistema Acertos Falsos Positivos Falsos Negativos Revocação Precisão v1 0 0 4 0% - Tabela V D ETECÇÃO S ENSÍVEL À H ISTÓRIA NO H EALTH WATCHER God Class (GC) v2 v3 v4 v5 v6 v7 0 0 1 0 0 1 0 0 0 0 0 0 4 4 3 3 3 2 0% 0% 25% 0% 0% 33% 100% 100% também seja suportada a hipótese nula de H2. Ou seja, estratégias sensíveis à história podem ser mais eficazes que estratégias convencionais. Tabela VI M ÉDIAS DOS RESULTADOS DAS ESTRATÉGIAS NO H EALTH WATCHER Estrat. Sensíveis à História Estrat. Convencionais God Classes (GC) Avg. Revocação 10% 0% Avg. Precisão 33% 0% VI. C ONCLUSÕES E T RABALHOS F UTUROS Nesse trabalho refinamos o conceito original de estratégias de detecção para que tal mecanismo considerasse o uso de métricas relacionadas à evolução de propriedades do código. Tal abordagem foi chamada de Estratégias de Detecção Sensíveis à História e para sua composição foram definidas métricas sensíveis à história. Além disso, para viabilizar a utilização da abordagem foi desenvolvida uma ferramenta capaz de dar suporte às avaliações de código. Um estudo foi realizado para avaliar as estratégias no contexto de uma linha de produto e de um sistema web, ambos desenvolvidos com a necessidade de se priorizar requisitos de modularidade. As estratégias possibilitaram a detecção de anomalias clássicas como God Class, Divergent Change e Shotgun Surgery com elevada precisão e revocação no primeiro sistema avaliado. No segundo sistema, em que o histórico de evolução era menos expressivo, as estratégias não se apresentaram tão eficazes, mas ainda geraram resultados mais significativos que os obtidos por estratégias convencionais. Para possibilitar um conhecimento maior sobre os benefícios e restrições de estratégias de detecção desse tipo outros estudos são necessários. Esses podem compreender sistemas com um maior número de versões e ainda a utilização direta de informações de ferramentas de gerência de configuração. As análises geradas nesse trabalho fornecem insumos que motivam estudos que associem informações do histórico de evolução do código com a detecção de anomalias. Tais estudos podem trazer importantes contribuições a sistemas caracterizados pela necessidade de se priorizar modularidade e manutenibilidade. R EFERÊNCIAS [1] A. J. Riel, Object-Oriented Design Heuristics. Boston, MA, USA: Addison-Wesley Longman Publishing Co., Inc., 1996. [2] M. Fowler, K. Beck, J. Brant, W. Opdyke, and D. Roberts, Refactoring: Improving the Design of Existing Code. Addison-Wesley, Reading, MA, USA, 1999. [3] J. Buckley, T. Mens, M. Zenger, A. Rashid, and G. Kniesel, “Towards a taxonomy of software change: Research articles,” J. Softw. Maint. Evol., vol. 17, no. 5, pp. 309–332, 2005. [4] D. Ratiu, S. Ducasse, T. Gîrba, and R. Marinescu, “Using history information to improve design flaws detection,” in CSMR ’04: Proceedings of the Eighth Euromicro Working Conference on Software Maintenance and Reengineering (CSMR’04). Washington, DC, USA: IEEE Computer Society, 2004, p. 223. v8 0 0 3 0% - v9 1 0 2 33% 100% v10 0 1 3 0% 0% [5] D. Ratiu, S. Ducasse, T. Girba, and R. Marinescu, “Evolution-enriched detection of god classes,” in In Proceedings of the 2ndWorkshop on Computer Aided Verification of Information Systems (CAVIS), 2004, pp. 3–7. [6] W. Pree and H. Sikora, “Design patterns for object-oriented software development (tutorial),” in ICSE ’97: Proceedings of the 19th international conference on Software engineering. New York, NY, USA: ACM, 1997, pp. 663–664. [7] S. R. Chidamber and C. F. Kemerer, “A metrics suite for object oriented design,” IEEE Trans. Softw. Eng., vol. 20, no. 6, pp. 476–493, 1994. [8] B. Henderson-Sellers, Object-oriented metrics: measures of complexity. Upper Saddle River, NJ, USA: Prentice-Hall, Inc., 1996. [9] R. Marinescu, “Detection strategies: Metrics-based rules for detecting design flaws,” in ICSM ’04: Proceedings of the 20th IEEE International Conference on Software Maintenance. Washington, DC, USA: IEEE Computer Society, 2004, pp. 350–359. [10] M. Lanza, R. Marinescu, and S. Ducasse, Object-Oriented Metrics in Practice. Secaucus, NJ, USA: Springer-Verlag New York, Inc., 2006. [11] E. Figueiredo, C. Sant’Anna, A. Garcia, and C. Lucena, “Applying and evaluating concern-sensitive design heuristics,” in SBES ’09: Proceedings of the 2009 XXIII Brazilian Symposium on Software Engineering. Washington, DC, USA: IEEE Computer Society, 2009, pp. 83–93. [12] Together. [Online]. Available: http://www.borland.com/br/products/together/ [13] incode. [Online]. Available: http://loose.upt.ro/incode/pmwiki.php/ [14] iplasma. [Online]. Available: http://loose.upt.ro/iplasma/ [15] infusion. [Online]. Available: http://www.intooitus.com/inFusion.html [16] C. J. van Rijsbergen, “Getting into information retrieval,” pp. 1–20, 2001. [17] E. Figueiredo, N. Cacho, C. Sant’Anna, M. Monteiro, U. Kulesza, A. Garcia, S. Soares, F. Ferrari, S. Khan, F. Castor Filho, and F. Dantas, “Evolving software product lines with aspects: an empirical study on design stability,” in ICSE ’08. New York, NY, USA: ACM, 2008, pp. 261–270. [18] T. Girba, S. Ducasse, and M. Lanza, “Yesterday’s weather: Guiding early reverse engineering efforts by summarizing the evolution of changes,” in ICSM ’04. Washington, DC, USA: IEEE Computer Society, 2004, pp. 40–49. [19] V. R. Basili, G. Caldiera, and H. D. Rombach, “The goal question metric approach,” in Encyclopedia of Software Engineering. Wiley, 1994. [20] S. Olbrich, D. S. Cruzes, V. Basili, and N. Zazworka, “The evolution and impact of code smells: A case study of two open source systems,” in ESEM ’09: Proceedings of the 2009 3rd International Symposium on Empirical Software Engineering and Measurement. Washington, DC, USA: IEEE Computer Society, 2009, pp. 390–400. [21] A. van Deursen, P. Klint, and J. Visser, “Domain-specific languages: an annotated bibliography,” SIGPLAN Not., vol. 35, no. 6, pp. 26–36, 2000. [22] P. Hudak, “Building domain-specific embedded languages,” ACM Comput. Surv., p. 196. [23] Hist-inspect. [Online]. Available: http://www.inf.puc-rio.br/l̃silva [24] R. Shatnawi and W. Li, “An investigation of bad smells in object-oriented design,” in ITNG ’06: Proceedings of the Third International Conference on Information Technology: New Generations. Washington, DC, USA: IEEE Computer Society, 2006, pp. 161–165. [25] P. Greenwood, T. Bartolomei, E. Figueiredo, A. Garcia, N. Cacho, C. Sant’Anna, P. Borba, Uirakulesza, and A. Rashid, “On the impact of aspectual decompositions on design stability: An empirical study,” in ECOOP 2007, ser. LNCS. Springer-Verlag, 2007, pp. 176–200. [26] M. Saleh and H. Gomaa, “Separation of concerns in software product line engineering,” in MACS 05. New York, NY, USA: ACM, 2005, pp. 1–5. [27] G. Carneiro, C. Sant’Anna, A. F. Garcia, C. v. F. G. Chavez, and M. G. Mendonça, “On the use of software visualization to support concern modularization analysis,” in ACoM 09, Florida, USA, 2009.