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.
Download

Detecting Modularity Flaws of Evolving Code: What the History can