The metrics introduced in this chapter are defined at the class level, system level, and class-dependency level. The main focus is on the reduction metrics for dependencies, while the class metrics and system metrics are used as a basis to define them. Figure 25 indicates the relationships between basic and derived metrics by arrows (with the derived metric at the arrows’ head).
Chapter 11: Metrics 125
Figure 25 Overview of metrics
11.2
Class Metrics
This section describes the metrics CD, CDh, and CDsh, which measure coupling characteristics at the class level and which are later used to define system-level metrics.
11.2.1
Metric CD
Metric CD measures the degree to which a given class depends on other classes directly as well as indirectly.
Definition
For a class c, metric CD(c) is defined as the number of direct and indirect supplier classes of c.
ACD ACDh ACDsh system metrics CD CDh CDsh class metrics NCDC NFD DSTMh dependency metrics DSTM rACD rACDh rACDsh rNCDC rNFD rACDin rACDout Properties of metric CD
name class dependency entity class
attribute coupling category direct metric scale type absolute scale
context Class::CD() : Integer
126 Chapter 11: Metrics
Motivation and Purpose
The reasons to select this metric are:
• it is used to define metric ACD (see Section 11.3.1).
• it is simple to calculate. This avoids complex and time-inten- sive computation of (reduction) metrics based on it.
• it is simple to interpret.
• It can be applied to early software analysis and design dia- grams, where information about class members (usually required by coupling metrics) is not available or incomplete. The metric can be used:
1 to characterize the coupling of a given class to other classes within the system and
2 to predict the time required for (re-)compiling all supplier classes before testing the class.
Note: We also expect a good correlation between the values of this metric and the difficulty to design test cases or to isolate faults. This is an open issue for further research.
Assumptions
Basic assumptions of the metric CD are: 1 Indirect dependencies do matter.
2 The size and complexity of the classes does not matter. 3 The effect of indirect dependencies on the investigated
attribute does not depend on the level of indirection.
4 Dependencies on concrete classes, abstract classes, and interfaces do have the same effect on the investigated attribute.
5 The category of the dependency does not matter. Discussion
Ad assumption 1: Metric CD takes into account indirect depen- dencies while the majority of all other coupling metrics does not1. Since indirect dependencies do have relevant effects on testing (as described in Section 2.4), it is important to consider them.
The assumptions 2, 3 and 4 from above are a strong simplifica- tion. However, more complex metrics are more difficult to inter-
1 Out of 30 coupling metrics described in [Bria96], only metric RFC’ and RFCD consider indirect dependencies.
Chapter 11: Metrics 127
pret and require a more thorough understanding of the relation- ship between program structure and test tasks:
• Ad assumption 3: It would be possible to define metrics that weight the contribution of indirect dependencies by the level of indirection if the effect of the level of indirection on the attribute under investigation can be quantified sufficiently. A draw-back of weighting is, that the metric values are more difficult to interpret and compare.
• Ad assumption 4: The type of the supplier class is relevant for some test tasks (e.g. for testing a class in isolation), for some it is not (e.g. for instantiating the supplier instances during test setup). However, not enough information is avail- able on the effect of the type of the supplier class on the test tasks to use an approach based on weigthing.
Related Metrics
A related metric is metric CBO (coupling between object classes) [Chid94] which differs from metric CD in the following ways:
• Metric CBO counts all dependencies irrespective of their direction while metric CD only considers outgoing dependen- cies.
• Metric CBO only counts method calls and attributes access while metric CD considers all kinds of dependencies between classes including inheritance relationships.
11.2.2
Metrics CDh and CDsh
Metric CDh and metric CDsh are different from metric CD by tak- ing into account the category of the dependencies: Metric CDh only considers hard-wired dependencies, while metric CDsh considers semi-hard-wired as well as hard-wired dependencies.
Properties of metric CDh
name class dependency caused by hard-wired dependencies entity class
attribute ability to test class in isolation category direct metric
scale type absolute scale
Properties of metric CDsh
name class dependency caused by semi-hard-wired and hard- wired dependencies
128 Chapter 11: Metrics
Definition
For a class c, metric CDh(c) is defined as the number of classes c depends on because of hard-wired dependencies:
For a class c, metric CDsh(c) is defined as the number of classes c depends on because of semi-hard-wired as well as hard-wired dependencies:
Motivation and Purpose
The metrics can be used for different purposes:
1 To characterize the degree to which a class is hard-wired (or semi-hard-wired) to other classes.
2 To predict the ability to test a class in isolation.
attribute ability to test class in isolation category direct metric
scale type absolute scale
context Class def
let directHwSuppliers(c: Class) : Set(Class) =
c.classDependency[supplier]->select(isHardWired())-> collect(supplier)->asSet()
let directHwSuppliersOfSet(s: Set(Class)) : Set(Class) = s->collect(c : Class | c.directHwSuppliers())->asSet() let reachableClassesHw(rc: Set(Class)) : Set(Class) =
if rc->includesAll(directHwSuppliersOfSet(rc)) then rc
else reachableClassesHw(rc->union(directHwSuppliersOfSet(rc))) context Class::CDh() : Integer
post: result = self.reachableClassesHw(Set{self})->excluding(self)->size()
context Class def
let directSHwSuppliers(c: Class) : Set(Class) =
c.classDependency[supplier]->select(isHardWired() or isSemiHardWired())->collect(supplier)->asSet() let directSHwSuppliersOfSet(s: Set(Class)) : Set(Class) =
s->collect(c : Class | c.directSHwSuppliers())->asSet() let reachableClassesSHw(rc: Set(Class)) : Set(Class) =
if rc->includesAll(directSHwSuppliersOfSet(rc)) then rc
else reachableClassesSHw(rc->union(directSHwSuppliersOfSet(rc))) context Class::CDsh() : Integer
post: result = self.reachableClassesSHw(Set{self})->excluding(self)-> size()
Chapter 11: Metrics 129
Metrics CDh and CDsh are the basis to define related system metrics (see Section 11.3).
Assumptions
Basic assumptions of the metrics CDh and CDsh are: 1 Each supplier class shall be stubbed.
2 Indirect dependencies do matter.
3 The size and complexity of the classes does not matter. 4 The effect of indirect dependencies on the investigated
attribute does not depend on the level of indirection. 5 The category of the dependency does matter. Discussion
Metrics CDh and CDsh are linked to the test task of testing a class in isolation. This distinguishes these metrics from existing coupling metrics which are general purpose metrics.
11.3
System Metrics
This section describes the metrics ACD, ACDh, ACDsh, NCDC, and NFD which address the effect of indirect dependencies, hard-wired dependencies, and dependency cycles on the sys- tem. The metrics can be used to characterize the dependency structure of a system, but their main purpose within the context of this work is to provide a basis for the definition of related reduction metrics.
11.3.1
Metric ACD
Metric ACD measures the degree to which classes of a system depend directly and indirectly on other classes within the sys- tem.
Properties of metric ACD
name average class dependency entity system
attribute system coupling
category indirect metric (based on metric CD and number of classes within the system)
130 Chapter 11: Metrics
Definition
For a system s, metric ACD(s) is defined as the average of met- ric CD for all classes of s:
Motivation and Purpose This metric can be used:
1 to characterize the average coupling between the classes of a system and
2 to predict the average time required to (re-)compile those parts of the system which are effected by a change.
Like for metric CD, we expect a good correlation with the diffi- culty to design test cases and to isolate faults, but this needs fur- ther research.
Other metrics (like the coupling metrics described in Appendix C) can be used to evaluate the structure of a system, too. The reasons why we define and use metric ACD are:
• Direct and indirect dependencies are relevant for testing. Metric ACD is sensitive to both of them.
• Metric ACD is simple to calculate. (This reduces the time required to calculate the metrics based on metric ACD.) • it is simple to interpret.
• It can be applied to early software artifacts like analysis and design diagrams when information at class member level is not available or incomplete (most existing coupling metrics require such information).
Assumptions
The assumptions for metric ACD are the same as for metric CD (Section 11.3.1).
Discussion
Since metric ACD is based on metric CD the discussion of met- ric CD applies as well: Metric ACD is based on a very abstract view of the system because each class is represented as a node within a graph, neglecting differences in size, complexity, or class type. This metric therefore provides only a rough view of
context System::ACD() : Real
post: if self.class->size() = 0 result = 0
else result = self.class->iterate(c : Class; sum : Integer = 0 | sum = sum + c.CD()) / self.class->size()
Chapter 11: Metrics 131
the system structure and is not well suited to compare different systems (because it is not normalized).
Interpretation of metric values
To interpret a value of metric ACD, compare it with the number of classes within the system and consider the average size and complexity per class.
Related Metric
John Lakos [Lako96] defined the metric “Average Component Dependency” to predict the average effort to recompile a class. It differs from our metric ACD by adding 1 to the value of metric CD for each class. This shall account for the fact, that not only the supplier classes have to be compiled but the client classes as well.