Mellow out with Afferent Coupling

There are a number of hip coupling metrics; however, two of the more interesting ones are Afferent Coupling and Efferent Coupling. These integer based metrics represent a count of related objects. Both Afferent Coupling and Efferent Coupling signify an architectural maintenance issue: either an object has too much responsibility (high Afferent Coupling) or the object isn’t independent enough (high Efferent Coupling).

Having too much responsibility isn’t necessarily a bad thing and understanding the implications of this copasetic metric can facilitate better decision making. Often, components (or packages or namespaces, etc) are intended to be utilized throughout an architecture, which in turn gives these components high afferent coupling values. Core frameworks, utilities like logging packages, and even exception hierarchies usually have high afferent coupling.

For example, the following diagram shows a package, com.acme.ascp.exception, with an Afferent Coupling of four. This isn’t a surprise, as the web, dao, util, and frmwrk packages would except to utilize a common exception framework.

As demonstrated in the above diagram, the exception package has an Afferent Coupling or Ca of 4, which in this case isn’t a terribly tripped out thing. Exception hierarchies rarely change dramatically; however, if there were drastic changes to the behavior or contract of exceptions in this package, there would be ripple effects throughout those four dependent packages.

Interestingly, by further examining the exception package and noting the ratio of abstract (i.e. Interfaces and Abstract declarations) to concrete classes, another metric can be derived: Abstractness. In this case, the exception package has an abstractness of zero as all classes are concrete. This correlates with the notes in the previous paragraph- because of the high degree of concreteness in this package, any changes will have a ripple affect.

By understanding that Afferent Coupling denotes a component’s responsibility and monitoring this value over time, teams who wish to keep on truckin’ can shield architectures from the inevitable entropy that, some would say, naturally occurs in even the most well designed, smokin’ systems.

Many architectures are designed with flexibility in mind when utilizing third party packages. Flexibility is ideally gained by shielding the architecture from changes within third party packages with interface packages. For example, designers could create an internal interface package that utilizes the third party billing code, but only exposes interfaces to those packages which require the use of billing code.

As the image above demonstrates, the acme.ascp application’s coupling to the third party billing package is through the com.acme.ascp.billing package. This creates a level of flexibility- if another billing package from another third party becomes more advantageous to utilize then only one package is affected. What’s more, com.acme.ascp.billing’s Abstractness value is 0.8, which indicates modifications can be shield via interfaces and abstract classes.

In the case of switching third party implementations, the com.acme.ascp.billing package becomes the area where surgical refactoring becomes necessary. Even better, by designing in this flexibility and understanding the implications of change, teams can protect themselves from collateral damage caused by modifications through developer testing.

Before any changes are made to the internal billing package, teams could analyze a code coverage report to verify if any tests actually hit this package. If there is some level of coverage, then a closer examination of test cases could be performed to verify adequacy.

As alluded to earlier, entropy has a way of working itself into the most well planned architectures. Either through team attrition or poorly documented intents, uninitiated developers can inadvertently import what appears to be a useful package, and before long, Afferent Coupling values begin to grow.

For example, compare the below image with the diagram above. Notice the brittleness that is now present within the architecture? Not only does the dao package directly utilize the third party billing package, but another package which wasn’t even intended to use any billing code directly references both billing packages!

Attempting to switch out the com.third.party.billing package for another one is going to be a challenging task indeed (worse than a bad disco acid flashback)! Imagine the test scaffolding that would be required to mitigate risks in this situation. In fact, architectures like the one depicted above rarely change as they can’t support modifications. Worse, when modifications are made, such as upgrades to existing components, things break throughout the code base.

Afferent Coupling, as reported by tools like JDepend and NDepend, is one of a few helpful architectural metrics that should be monitored over time. Doing so facilitates maintainable code bases because as we all know in this Age of Aquarius, code has a way of living much, much longer than we ever intend it to. Dig it?

Related odds and ends
 

One Response to “Mellow out with Afferent Coupling”


  1. [...] Clearly, background information on the owner of the account certainly helps put into perspective how one would view the funds available. Similarly, with software metrics, the same lesson holds true– the application being measured needs to be considered in context during analysis . Applications built to run on a wrist watch will most likely yield metrics quite different and even considered harmful if they we obtained from a copacetic web application, for instance. [...]

Trackback this Post | Feed on comments to this Post

Leave a Reply