SourceForge.net Logo


Metrics Analysis Set 2/20/2003


Metrics Used From jMetra:

Observing the LOCC at the application level, it seems to imply that the project grew in complexity over the first 4 versions and then was refactored and cleaned up in the last version. This is encouraging and should be noted as good practice for future iterations.

The method count metric did not coincide with the refactoring approach described in the LOCC analysis. If refactoring did truly occur, one would expect to see the method count climb proportional to the amount of code that was refactored. The implication of this data shows that in fact the code was not really refactored, but indeed made less complex overall to achieve the lower line count in the last version.

The class count metric goes on to prove that significant re-architecting was completed in the last version or that significant functionality was actually pulled out from the entire application.

 Further analysis shows that the services and gui packages were fairly stable from version 3 onwards. They both only include minimal changes which seem to have added lines of code, methods, and classes. The most significant contributor to these metrics seems to have been the app package. The app package seems to have shrunk in line, method, and class count. In retrospect, most of that package was inherited from some sample open source code. Since we brought in most of the open source code and stripped out what was unncessary in the latest revision, it shows through the metrics that we have cleaned up and reduced the total lines, methods, and classes.

 We can use the knowledge learned about how metrics are collected to make notes of significant changes between revisions (such as the one listed in the conclusion above) so that we can discount such major changes in finding useful information about refactoring and clean up to show that we are likely to have readable and modular code. Showing the relative numbers for method and line counts can also help show the likeliness of bugs and other artifacts that our code may carry based on the analysis.


 Metrics Used From Martin: (no longer functions with update jxta build)

Analyzing the results of the Martin Metrics produced interesting and useful insight into the design of our system.  The results allowed us to target areas that should be analyzed and refactored in order to improve the reusability of our classes and make them less sensitive to change.

 

Afferent and Efferent Coupling alone are not very useful as an analytical metric.  The metric for Efferent Coupling was much higher than the metric for Afferent Coupling.  This is not unusual for a system developed in Java because the classes that the developer creates often depend heavily on classes that are built into the Java language.  Where Afferent and Efferent Coupling become more powerful metrics is in their ability to calculate the Instability metric.  The three packages analyzed (app, gui, services) have Instability values of .962, .973, and .636.  These metric values show that the classes in the three packages are not used by a large number of other packages, however they do depend on a number of other packages.  The three packages can be easily changed because few others depend on them. 

 

App, gui, and services packages all had the value of 0 for the Abstractness metric.  This means that the classes in the three packages cannot be extended.  This is not necessarily a negative attribute of a package.  In order to analyze the effect of a 0 abstractness value we must move on to the Distance from the Main Sequence metric.

 

The idea behind the Distance from the Main Sequence metric is that the more abstract a package is the more stable it should be.  So it is ideal for a package to have a either A=0 and I=1, or for it to have A=1 or I=0.  Actually, a good package will have a balance between abstractness and instability. In other words if placed as a point on the graph below the values of A and I should fall on or close to the Main Sequence line.

 

 

 

Packages should have a normalized value for the Distance from the Main Sequence metric of near zero.  A value close to zero represents that the package is close to the Main Sequence.  This type of package is more reusable, and less sensitive to change.  The app and gui packages in our system had normalized Distance values of -.038 and -.027 respectively, which is good.  However, the normalized Distance value for the services package deviated further from zero to a value of   -.364.  The classes in the services package should be examined and refactored.  A greater number of classes in other packages depend on the classes in services, in comparison to the dependence on the classes in app and gui.  When refactoring services the developers need to create more abstract classes or reduce the amount of outside dependencies on its classes.


Metrics Used From RevJava:

 There are a number of classes that show a high level of inheritance.  At a depth of 6, the gui classes still ok considering that java gui usage typically results in high inheritance depth.  The average method for our code came out to 27.  Revjava discovered several large methods including discoverEvent at 147 lines inside of PeerDiscovery and method int inside of each GUI related screens.  Other notable results include a high occurrence of critics about breaking the Law of Demeter but mostly when classes are working with the user interface.  It is also obvious from the metrics on which methods are yet to be implemented by the fact that they are marked as unused.  It is possible that some of these unused methods should in fact be removed.    Out of three packages for the system, the services package has a total method size of 257, apps package has a method size of 476, while the gui method size is a whopping 2384.  Apparently much of the current functionality is contained within the gui package.  The gui should be separated from the code logic and therefore the apps and services packages may need to contain some of the functionality found within the gui package.  Upon further inspection, the gui package contains 20 classes while the apps and services contain a mere 6 classes.  The 20 classes represent 20 different screens in the system.  Each class in the gui package averages 2.7 methods per class so it’s understandable why the gui package is large relative to the rest of the system.  From this, we can tell that the gui package is ahead of the rest of the system.  More effort should be placed on implementing features represented with the gui package to the user.   


RMS and JMT Analysis

Examine method complexities

            The majority of methods in our application have low cyclomatic complexities, but two methods stand out:  StatusScreen.updatePeerVector in the GUI package and PeerDiscovery.discoveryEvent in the Services package.  These methods have cyclomatic complexity twelve and eleven respectively, and should be examined to see if such complexity is truly necessary.  If these methods cannot be simplified, we must be sure to focus increased testing efforts on them.

Visibility of Constructors

            Comparison of the Public Interface Methods and Methods per Class metrics revealed that in the GUI package, all constructors have package visibility, while in the other packages, the constructors have public visibility.  We should determine whether this difference is by design or if there is an inconsistency in the application that should be remedied.

Lack of Private Methods

            The comparison of the Public Interface Methods and Methods per Class metrics also reveals that there are very few private methods in the application.  It is possible that the complexity of our methods, particularly the two mentioned in 6.1 above, could be reduced by adding private helper methods to the classes.

Inconsistent Method Counts

            In some cases, we ran different tools searching for the same metric so that we could gain confidence in our results.  We discovered that JMT and RSM produced parallel but separate results sets when counting the number of methods in each class.  We determined that this is due to a difference in the tools ability to parse inner classes; while RMS excludes the methods of inner classes in its count for a class, JMT includes them.  We think that both methods are valid, and enjoy having both, because a large difference might indicate a class with an overly complex set of inner classes.