Neste trabalho, são estudadas seis métricas de software que foram selecionadas por serem relacionadas a fatores influentes na qualidade estrutural de software, tais como acoplamento, coesão, encapsulamento, ocultação de informação e profundidade da árvore de herança. Essas métricas são descritas a seguir.
COF (Coupling Factor) [Abreu & Carapuça, 1994]: esta métrica é calculada em nível de sistema. O sistema é representado por um grafo direcionado sem self-loops no qual os vértices são as classes e as arestas, as conexões entre as classes. No cálculo dessa métrica, considera-se que há uma conexão direcionada de A para B quando A usa um serviço ou atributo de B ou é sub-classe de B. Em um software
com n classes, pode haver no máximo n2− n conexões. COF é dado por c/(n2−
n), onde c é o número de conexões existentes no software. Esta métrica é um indicador do grau de conectividade do software. Como afirmado por Meyer [1997], em uma arquitetura de software “cada módulo deve se comunicar com o menor número possível de outros módulos”. Quanto maior COF, maior a conectividade do software, o que pode contribuir para a dificuldade de manutenção do software [Abreu & Carapuça, 1994].
Número de atributos públicos: esta métrica é o total de número de atributos públicos definidos em uma classe. Um dos conceitos principais do paradigma orientado por objetos é a ocultação de informação, que define que um módulo deve revelar o mínimo possível de seu funcionamento interno. Para atender esse princípio, é desejável evitar tornar dados públicos. Um atributo público pode ser direta- mente acessado e alterado por qualquer outro objeto. Desta forma, o uso de atributos públicos pode levar ao surgimento de forte acoplamento entre classes de um software, reduzindo a modularidade do programa [Fowler, 1999; Meyer, 1997].
Número de métodos públicos: esta métrica é o total de métodos públicos definidos na classe. Como um método público corresponde a um serviço provido pela classe, esta métrica é um indicador da quantidade de serviços realizados pela classe. Como afirmado por Fowler [1999], quando uma classe possui um número grande métodos é um sinal de que ela pode ter muitas responsabilidades, o que pode tornar difícil o seu entendimento e sua manutenção.
LCOM (Lack of Cohesion in Methods) [Chidamber & Kemerer, 1994]: esta métrica mede o grau de coesão interna de uma classe considerando o conceito de simi- laridade entre métodos. Dois métodos são considerados similares se eles usam pelo menos uma variável de instância da classe em comum. LCOM é dada pela diferença entre o número de pares de métodos similares e o número de pares de métodos não similares. Por definição, quando o número de pares sem similari- dade é menor do que o número de pares de métodos com similaridade, LCOM é igual a 0. De acordo com Chidamber & Kemerer [1994], quanto maior o valor de LCOM, menor a coesão da classe. Entretanto, o valor zero não corresponde necessariamente à boa coesão.
Há uma grande quantidade de métricas de coesão propostas para a orientação por objetos e LCOM tem sido criticada na literatura [Briand et al., 1998]. Apesar disso, LCOM foi avaliada no presente estudo porque ainda não há uma con-
5.2. Metodologia 67
clusão consensual sobre a melhor forma de se medir coesão interna de classe. Além disso, outras métricas de coesão são baseadas na mesma ideia de similari- dade usada por LCOM. Aqui não se faz nenhuma afirmação sobre a validade de LCOM. O escopo deste trabalho é identificar os valores comuns desta métrica na prática, provendo valores referência para aqueles que a utilizam. Um estudo de Lincke et al. [2008] analisou dez ferramentas de coleta de métricas para progra- mas Java. Oito destas ferramentas coletam LCOM de acordo com sua definição original feita por Chidamber & Kemerer [1994], enquanto apenas três coletam uma nova versão da métrica. Desta forma, LCOM parece ser utilizada apesar das críticas que tem sofrido.
DIT (Depth of Inheritance Tree) [Chidamber & Kemerer, 1994]: esta métrica é dada pela distância máxima de uma classe à raiz da sua árvore de herança. Herança é uma técnica poderosa de reuso de software. Entretanto, Gamma et al. [2000] afirmam que o uso imoderado de herança pode tornar a estrutura do software complexa. Eles, então, definem o princípio: favoreça composição de objetos em relação à herança. Na mesma linha, Sommerville [2003] argumenta que herança introduz dificuldades na compreensão de comportamento de objetos. Um estudo empírico de Daly et al. [1996] mostrou que árvores de herança profundas torna a manutenção de software mais difícil. DIT indica a profundidade de uma classe na sua árvore de herança. Esta métrica é considerada um indicador da complexidade do desenho do software [Chidamber & Kemerer, 1994]. Quanto maior o valor de DIT de uma classe, maior o número de classes envolvidas na sua análise e mais difícil a sua compreensão.
Conexões aferentes: um software pode ser representado como um grafo direcionado, sem self loops, no qual os vértices representam as classes, e as arestas, as conexões entre as classes. No cálculo dessa métrica, considera-se que há uma conexão direcionada de A para B quando A usa um serviço ou um atributo de B ou é sub-classe de B. A métrica é dada pelo total de conexões (arestas) que chegam a uma classe. Ela é um indicador do número de classes no software que dependem da classe avaliada. Classes que possuem um alto número de conexões aferentes desempenham um papel central no sistema, pois erros ou modificações nelas podem afetar um grande número de outras classes. Um valor alto de conexões aferentes em uma classe pode ser um sinal de que ela desempenha muitas res- ponsabilidades. Esta métrica ajuda a identificar tais classes, para que se possa ter uma noção melhor dos impactos de modificações realizadas nela ou avaliar a necessidade de reestruturá-las.