“You cannot control what you cannot measure.”
(by Tom De Marco)
“Measurement” is a fundamental activity to any engineering discipline. Measuring and quantifying aspects associated with a system of interest help us understand the characteristics of the system and pave the way to derive interpretations and insights about the system.
In the context of software systems, there are numerous kinds of metrics associated with different aspects of software and software development such as product or process metrics where product metrics can be further classified as static and dynamic metrics and even further such as code, requirement, or test metrics. A software metric is a measure of some property of a software system.
This post focuses on static code and design metrics to reveal the structural health of a software system and discusses different metric types, their meaning and interpretations as well as a few tools that could be helpful identifying such metrics.
Table-1 summarizes metrics commonly used to analyze maintainability of a software system. These metrics can be classified in three broad categories viz. size, complexity, and cohesion and coupling. Let us take a deeper look at these metrics.
Table 1: Software Metrics and their categories
1. Size Metrics
Each software entity must be of moderate size. Large entities are difficult to understand, use, reuse, and test. Often, large entities implement more than one responsibility and violate Single Responsibility Principle (SRP). Table-2 shows description and typical threshold used for each metric concerning size.
Table 2: Size metrics with description and typical threshold
Metric | Description | Threshold |
LOC | Lines Of Code – Total lines of code in a source-code entity | Method – 80, Type - 1000 |
NOM | Number Of Methods – Total number of methods in a type | 30 |
NOF | Number Of Fields – Total number of fields in a type | 20 |
DIT | Depth of Inheritance Tree – Maximum length of the path from this type to root of the inheritance tree | 6 |
NC | Number of Children – Total number of sub-classes of a type | 10 |
NOC | Number Of Classes – Total number of types in a namespace | 20 |
NON | Number of Namespaces – Total number of namespaces in a project | 5 |
NP | Number of Parameters – Total number of parameters in a method | 6 |
A note about thresholds – The thresholds presented in the above table (and throughout this article) are indicative and may change based on organization or project code quality guidelines.
2. Complexity Metrics
Cyclomatic Complexity (CC) is a commonly used metric to measure the complexity of a method. It indicates a total number of possible unique paths from the beginning of a method to exit the method. It is considered crucial since a high value of CC in a method indicates high number of tests required to cover all the paths in the method (In fact, minimum number of tests must be written for the method is equal to CC). Weighted Methods per Class (WMC) is the sum of cyclomatic complexities of all the methods belonging to the class. Table-3 lists the complexity metrics with description and associated thresholds.
Table 3: Complexity metrics with description and associated typical threshold
Metric | Description | Threshold |
CC | Cyclomatic Complexity – Total number of linearly independent paths through a method | 5 |
WMC | Weighted Methods per Class – Sum of cyclomatic complexities of all the methods belonging to the class | 100 |
3. Cohesion and Coupling Metrics
We should strive for high cohesion and low coupling classes. A class with high cohesion means that the methods and fields in the class are implementing single responsibility and will be changed due to only a single reason. Similarly, a class with low coupling means that the class is well isolated from the rest of the software system and hence chances to introduce a change in the class due to changes in other classes are low. The metrics used to measure cohesion and coupling are listed in Table-4.
Table 4: Cohesion and coupling metrics with description and associated typical threshold
Metric | Description | Threshold |
LCOM | Lack of Cohesion of Methods – It is the lack of correlation between the methods and the instance variables of the class (typically represented as a normalized value between 0 and 1 (both included), low value is desired) | 0.8 |
CBO | Coupling Between Object classes – Number of other classes to which the class is coupled | 10 |
Fan-in | Fan-in – Total number of classes that reference the class (in-coming dependencies) | 20 |
Fan-out | Fan-out – Total number of classes referenced by the class (out-going dependencies) | 20 |
4. Computing and Analyzing Software Metrics
Visual Studio computes some of the metrics mentioned above; specifically, cyclomatic complexity, lines of code, depth of inheritance, and class coupling. Visual Studio also computes Maintainability index which could be used to infer the overall maintainability of the software. However, it is a composite metric which could not be used for further drill-down to carry out a deeper analysis if one wish to improve the maintainability of the software and wish to know specific pain areas.
There are numerous tools that we can use that helps us not only computing various software metrics but also analyze them. For example, Designite computes commonly used metrics and presents them in the form of an interactive pie chart (see Figure 1). The pie chart has four partitions viz. green, yellow, orange, and red. Designite computes metrics associated with types as well as methods and based on their values and pre-defined thresholds, it shows the distribution of entities that fall in each partition. By looking at the pie chart, one can instantly get an overall idea about the project code quality from the selected metrics point of view.
Figure 1: Detailed metrics analysis by Designite
Apart from showing a distribution of classes that falls in each of the pie, the pie chart can also be used as a navigation and filtering mechanism. For instance, if one clicks on the red pie, classes that are dangerously above the metric threshold will only be shown in the grid below the pie chart (not shown here). One can see other associated metrics for the filtered classes and may target these classes first for refactoring. Even further, one can change the thresholds (green, yellow, and orange) to customize the analysis.
A word of caution
Always consider metric values as indicators of code quality and not as an absolute line that must not be violated. A software with all entities in green with respect to all commonly used metrics may not be a high-quality code; however, a high-quality code will have most of the entities in green with respect to all metrics. In summary, strive for quality not for numbers.