|
The aim of this metric is to try and determine whether a class represents one abstraction (good) or multiple abstractions (bad). If a class represents multiple abstractions, it should be split up into multiple classes. The correct way to measure this property is a matter of hot debate among software metrics experts, so SemmleCode provides two ways of doing it: one due to
Henderson-Sellers, and another one due to Chidamber and Kemerer (described below).
The intuition behind the Chidamber and Kemerer metric is to inspect pairs of
methods. If there are many pairs that access the same data, then the class is
cohesive. On the other hand, if there are many pairs that do not access any
common data, then the class is not cohesive.
In the Chidamber and Kemerer method, this is measured as follows:
- n1 = number of pairs of distinct methods in a reftype that do
not
have at least one commonly accessed field
- n2 = number of pairs of distinct methods in a reftype that do
have at least one commonly accessed field
- LCOM = ((n1 - n2)/2 max 0)
We divide by 2 because each ordered pair (m1,m2) is counted twice in n1 and n2.
High values of LCOM indicate a lack of cohesion. Specifically,
an LCOM of greater than 500 indicates a potential problem.
Pre-packaged Queries
Query name = "Semmle/Metrics/Types/Cohesion/Reftypes that lack cohesion of methods (LCOM) in the Chidamber and Kemerer sense"
Reports reference types that have a lack of cohesion greater than 500, in decreasing order, as a bar chart.
from MetricRefType t, int loc
where loc = t.getLackOfCohesionCK() and loc > 500
select t, loc order by loc desc
Query name = "Semmle/Metrics/Types/Cohesion/Reftypes that lack cohesion of methods (LCOM) both according to HS and CK"
Reports reference types that have a lack of cohesion both in the sense of
Henderson-Sellers, and in the sense of Chidamber and Kemerer. Adds warnings
to Eclipse's problem view.
from MetricRefType t
where t.getLackOfCohesionCK() > 500 and
t.getLackOfCohesionHS() > 0.9
select t, "lacks cohesion of methods (LCOM)"
.QL Source of Metric
This metric is defined in the class MetricRefType. It reads:
// test for distinct methods
predicate distinctMembers(Method m1, Method m2) {
m1.getDeclaringType() = this
and
m2.getDeclaringType() = this
and
m1 != m2
}
// do m1 and m2 access a common field?
predicate shareField(Method m1, Method m2) {
exists(Field f |
m1.accesses(f) and
m1.getDeclaringType() = this and
m2.accesses(f) and
m2.getDeclaringType() = this)
}
// return Chidamber and Kemerer Lack of Cohesion
int getLackOfCohesionCK() {
exists(int n1, int n2, int n |
n1 = count(Method m1, Method m2 |
this.distinctMembers(m1,m2)
and
not(this.shareField(m1,m2)) |
1)
and
n2 = count(Method m1, Method m2 |
this.distinctMembers(m1,m2)
and
this.shareField(m1,m2) |
1)
and
n = (n1 - n2)/2
and
( (n < 0 and result = 0)
or
(n>=0 and result = n) )
)
}
Criticisms and Variations
One might not want to count static methods in this calculation. To make that
alteration, we define:
class MyMetricRefType extends MetricRefType {
predicate distinctMembers(Method m1, Method m2) {
super.distinctMembers(m1,m2) and
not(m1.hasModifier("static")) and
not(m2.hasModifier("static"))
}
}
from MyMetricRefType t, int loc
where loc = t.getLackOfCohesionCK() and loc > 500
select t, loc order by loc desc
An interesting, up-to-date study of the importance of cohesion and its
relationship with coupling metrics can be found in the
recent paper
by Darcy et al, cited below.
References
Victor Basili,
Lionel Brand and
Walcelio Melo.
A validation of object-oriented design metrics as quality indicators.
IEEE Transactions on Software Engineering, Volume 22, No. 10, pages 751-760. October 1996.
Shyam R. Chidamber and
Chris F. Kemerer.
A Metrics Suite for Object Oriented Design
.
IEEE Transactions on Software Engineering,
20(6), pages 476-493, June 1994.
David P. Darcy,
Sandra A. Slaughter,
Chris F. Kemerer,
James E. Tomayko.
The Structural Complexity of Software: An Experimental Test
.
IEEE Transactions on Software Engineering, 31(11), pages 982--995, 2005.
Diomides D. Spinnelis.
Code Quality: The Open Source Perspective.
Addison-Wesley 2007.
Diomides D. Spinnelis.
ckjm - Chidamber and Kemerer Java Metrics.
(implementation of CK metrics), 2006.
|