Software Engineering-Class Oriented Metrics

The class is the fundamental unit of an OO system. Therefore, measures and metrics for an individual class, the class hierarchy, and class collaborations will be invaluable to a software engineer who must assess design quality. In earlier chapters, we saw that the class encapsulates operations (processing) and attributes (data). The class is often the “parent” for subclasses (sometimes called children) that inherit its attributes and operations. The class often collaborates with other classes. Each of these characteristics can be used as the basis for measurement.

The CK Metrics Suite

One of the most widely referenced sets of OO software metrics has been proposed by Chidamber and Kemerer . Often referred to as the CK metrics suite, the authors have proposed six class-based design metrics for OO systems.

Weighted methods per class (WMC). Assume that n methods of complexity c1, c2, . . ., cn are defined for a class C. The specific complexity metric that is chosen (e.g., cyclomatic complexity) should be normalized so that nominal complexity for a method takes on a value of 1.0.

WMC = ci

for i = 1 to n. The number of methods and their complexity are reasonable indicators of the amount of effort required to implement and test a class. In addition, the larger the number of methods, the more complex is the inheritance tree (all subclasses inherit the methods of their parents). Finally, as the number of methods grows for a given class, it is likely to become more and more application specific, thereby limiting potential reuse. For all of these reasons, WMC should be kept as low as is reasonable

Although it would seem relatively straightforward to develop a count for the number of methods in a class, the problem is actually more complex than it seems. Churcher and Shepperd  discuss this issue when they write:

In order to count methods, we must answer the fundamental question ”Does a method belong only to the class which defines it, or does it also belong to every class which inherits it directly or indirectly?” Questions such as this may seem trivial since the runtime system will ultimately resolve them. However, the implications for metrics may be significant.

One possibility is to restrict counting to the current class, ignoring inherited members. The motivation for this would be that inherited members have already been counted in the classes where they are defined, so the class increment is the best measure of its functionality— what it does reflects its reason for existing. In order to understand what a class does, the most important source of information is its own operations. If a class cannot respond to a message (i.e., it lacks a corresponding method of its own) then it will pass the message on to its parent(s).

At the other extreme, counting could include all methods defined in the current class, together with all inherited methods. This approach emphasizes the importance of the state space, rather than the class increment, in understanding a class.

Between these extremes lie a number of other possibilities. For example, one could restrict counting to the current class and members inherited directly from parent(s). This approach would be based on the argument that the specialization of parent classes is the most directly relevant to the behavior of a child class.

Like most counting conventions in software metrics, any of the approaches just outlined is acceptable, as long as the counting approach is applied consistently whenever metrics are collected.

Depth of the inheritance tree (DIT). This metric is “the maximum length from the node to the root of the tree” . Referring to figure, the value of DIT for the class-hierarchy shown is 4. As DIT grows, it is likely that lower-level classes will inherit many methods. This leads to potential difficulties when attempting to predict the behavior of a class. A deep class hierarchy (DIT is large) also leads to greater design complexity. On the positive side, large DIT values imply that many methods may be reused.

Number of children (NOC). The subclasses that are immediately subordinate to a class in the class hierarchy are termed its children. Referring to figure, class C2 has three children—subclasses C21, C22, and C23. As the number of children grows, reuse increases but also, as NOC increases, the abstraction represented by the parent class can be diluted. That is, some of the children may not really be appropriate members of the parent class. As NOC increases, the amount of testing (required to exercise each child in its operational context) will also increase.

Coupling between object classes (CBO). The CRC model  may be used to determine the value for CBO. In essence, CBO is the number of collaborations listed for a class on its CRC index card. As CBO increases, it is likely that the reusability of a class will decrease. High values of CBO also complicate modifications and the testing that ensues when modifications are made. In general, the CBO values for each class should be kept as low as is reasonable. This is consistent with the general guideline to reduce coupling in conventional software.

Response for a class (RFC). The response set of a class is “a set of methods that can potentially be executed in response to a message received by an object of that class” . RFC is the number of methods in the response set. As RFC increases, the effort required for testing also increases because the test sequence grows. It also follows that, as RFC increases, the overall design complexity of the class increases.

Lack of cohesion in methods (LCOM). Each method within a class, C, accesses one or more attributes (also called instance variables). LCOM is the number of methods that access one or more of the same attributes. If no methods access the same attributes, then LCOM = 0. To illustrate the case where LCOM ≠ 0, consider a class with six methods. Four of the methods have one or more attributes in common (i.e., they access common attributes). Therefore, LCOM = 4. If LCOM is high, methods may be coupled to one another via attributes. This increases the complexity of the class design. In general, high values for LCOM imply that the class might be better designed by breaking it into two or more separate classes. Although there are cases in which a high value for LCOM is justifiable, it is desirable to keep cohesion high; that is, keep LCOM low.

Metrics Proposed by Lorenz and Kidd

In their book on OO metrics, Lorenz and Kidd  divide class-based metrics into four broad categories: size, inheritance, internals, and externals. Size-oriented metrics for the OO class focus on counts of attributes and operations for an individual class and average values for the OO system as a whole. Inheritance-based metrics focus on the manner in which operations are reused through the class hierarchy. Metrics for class internals look at cohesion  and code-oriented issues, and external metrics examine coupling and reuse. A sampling of metrics proposed by Lorenz and Kidd follows:

Class size (CS). The overall size of a class can be measured by determining the following measures:

The total number of operations (both inherited and private instance operations) that are encapsulated within the class.
The number of attributes (both inherited and private instance attributes) that are encapsulated by the class.

The WMC metric proposed by Chidamber and Kemerer  is also a weighted measure of class size. As we noted earlier, large values for CS indicate that a class may have too much responsibility. This will reduce the reusability of the class and complicate implementation and testing. In general, inherited or public operations and attributes should be weighted more heavily in determining class size . Private operations and attributes enable specialization and are more localized in the design. Averages for the number of class attributes and operations may also be computed. The lower the average values for size, the more likely that classes within the system can be reused widely.

Number of operations overridden by a subclass (NOO). There are instances when a subclass replaces an operation inherited from its superclass with a specialized version for its own use. This is called overriding. Large values for NOO generally indicate a design problem. As Lorenz and Kidd point out:

Since a subclass should be a specialization of its superclasses, it should primarily extend the services [operations] of the superclasses. This should result in unique new method names.

If NOO is large, the designer has violated the abstraction implied by the superclass. This results in a weak class hierarchy and OO software that can be difficult to test and modify.

Number of operations added by a subclass (NOA). Subclasses are specialized by adding private operations and attributes. As the value for NOA increases, the subclass drifts away from the abstraction implied by the superclass. In general, as the depth of the class hierarchy increases (DIT becomes large), the value for NOA at lower levels in the hierarchy should go down.

Specialization index (SI). The specialization index provides a rough indication of the degree of specialization for each of the subclasses in an OO system. Specialization can be achieved by adding or deleting operations or by overriding.

                   SI = [NOO level]/Mtotal

where level is the level in the class hierarchy at which the class resides and Mtotal is the total number of methods for the class. The higher is the value of SI, the more likely the class hierarchy has classes that do not conform to the superclass abstraction.

The MOOD Metrics Suite

Harrison, Counsell, and Nithi  propose a set of metrics for object-oriented design that provide quantitative indicators for OO design characteristics. A sampling of MOOD metrics follows:

Method inheritance factor (MIF). The degree to which the class architecture of an OO system makes use of inheritance for both methods (operations) and attributes is defined as

             MIF = Mi(Ci)/ Ma(Ci)

where the summation occurs over i = 1 to TC. TC is defined as the total number of classes in the architecture, Ci is a class within the architecture, and

            Ma(Ci) = Md(Ci) + Mi(Ci)

Ma(Ci) = the number of methods that can be invoked in association with Ci.
Md(Ci) ) = the number of methods declared in the class Ci.
Mi(Ci) = the number of methods inherited (and not overridden) in Ci.

The value of MIF (the attribute inheritance factor, AIF, is defined in an analogous manner) provides an indication of the impact of inheritance on the OO software.

Coupling factor (CF). Earlier in this chapter we noted that coupling is an indication of the connections between elements of the OO design. The MOOD metrics suite defines coupling in the following way:

CF = Σi Σj is_client (Ci, Cj)]/(TC2 -TC)

where the summations occur over i = 1 to TC and j = 1 to TC. The function 
is_client = 1, if and only if a relationship exists between the client class, Cc, and the server class, Cs,and                            Cc≠ Cs
              = 0, otherwise

Although many factors affect software complexity, understandability, and maintainability, it is reasonable to conclude that, as the value for CF increases, the complexity of the OO software will also increase and understandability, maintainability, and the potential for reuse may suffer as a result.

Polymorphism factor (PF). Harrison and her colleagues  define PF as “the number of methods that redefine inherited methods, divided by the maximum number of possible distinct polymorphic situations . . . [t]hus, PF is an indirect measure of the relative amount of dynamic binding in a system.” The MOOD metrics suite defines PF in the following manner:

               MIF = i Mo(Ci)/ i [Mn(Ci) DC(Ci)]

where the summations occur over i = 1 to TC and

               Md(Ci) = Mn(Ci) + Mo(Ci)


Mn(Ci) = the number of new methods.
Mo(Ci) = the number of overriding methods.
DC(Ci) = the descendants count (the number of descendant classes of a base class).

Harrison and her colleagues  present a detailed analysis of MIF, CF, and PF along with other metrics and examine their validity for use in the assessment of design quality.
Share this article :
Copyright © 2012. Best Online Tutorials | Source codes | Programming Languages - All Rights Reserved