Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Coupling, Abstractness, Stability – Measuring and Applying Code Metrics

In a comment to this post,
Darrell suggested I describe where high factors of coupling are
appropriate.  I’ll take it one step further and show you how to
use those factors to determine the stability of an assembly and
application, measure abstractness, and how to look at both to determine
how useful your assembly actually is.

Stability is measured by determining how easily you can change an
assembly without that change having impact on other assemblies within
the application.

An assembly with high afferent coupling (other assemblies depend on
it), which is a highly responsible assembly, is an assembly that has
lots of reuse throughout your application.  These assemblies are
also, by design, typically the most stable assemblies in the
application because assemblies with a high level of responsibility to
other assemblies are difficult to change without impacting its
dependents.  An example of a highly responsible assembly (high
afferent coupled assembly) would be an assembly that contains
business objects, because business objects get used throughout the
application, and if you change a business object, this has major impact
on the rest of the application.

An assembly with high efferent coupling (depends on other
assemblies), is an assembly that is highly dependent on other
assemblies in your application.  These assemblies are OK with
being instable, because changing them doesn’t involved a great deal of
impact on other assemblies within the application.  Highly
efferent coupled assemblies have little responsibility to the rest of
the application, but are highly dependent on the other
assemblies.  GUI layer assemblies (code-behind assemblies in
Asp.Net) are a prime example of high efferent coupled, low afferent
coupled assembly.

So now that we understand where afferent and efferent coupling takes
place, how do you use that to figure out the instability of your
assemblies?  Well, there is a formula for that:

I = Ce / (Ce + Ca)

Where:

  • I = degree of instability of an assembly ranging from zero to one
    • Zero indicates stability.  One indicates instability.
  • Ce = efferent coupling (outgoing dependencies)
  • Ca = afferent coupling (incoming dependencies)

The closer I is to zero, the more stable and responsible the assembly is.  This is an indication of more incoming dependencies (Ca) than outgoing dependencies (Ce).  Again, stable packages are difficult to change without impacting the rest of the application.  As I approaches one, this indicates a more instable, less responsible, more dependent, easier to change assembly.

So now, how do you make use of this?  You’re going to
have assemblies that are both stable and instable in your
application.  That’s the way things work.  You’re goal, as a
developer, is to make an assembly as close to stable (I = 0) or instable (I
= 1) as possible, given the particular assembly’s role in your
application.  You’ll goal isn’t actually to reach a value of zero
or one, but to get close to it.

In .Net, as in all OOP languages, we can use abstract classes to
increase the stability of an assembly.  Abstract classes pull away
what a class is supposed to do from how its actually done, which is
handled in an inheriting class.  Abstract classes are completely
stable classes themselves, and an assembly full of abstract types would
qualify as a completely stable assembly.  Concrete classes do work
and do not necessarily define what work.  Concrete classes
typically get the “what am I supposed to do” by inheriting from an
abstract class.  The concrete class then implements the “this is
how to do that work”.  Concrete classes are more instable, because
they encapsulate actual work and have less dependents/more dependencies.

So here’s the formula for determining the abstractness of an assembly:

A = Na / Nc

Where:

  • A = abstractness of an assembly
    • Zero is a completely concrete assembly. One is a completely abstract assembly.
  • Na = number of abstract classes in the assembly
  • Nc = number of concrete classes in the assembly

 By taking the design metrics we have talked about, you can
determine just how useful your assembly is.  If you have an
abstract assembly, but it is highly instable, you’ve really messed up
somewhere, because you have an assembly that doesn’t do any work, but
is highly dependent on other assemblies.  That is a very useless
assembly.  In constract, if you have a highly concrete assembly
that is also highly stable, you’re going to have a nightmare trying to
make changes to that assembly, because it is doing a lot of work, and
also is highly responsible to other assemblies in the application.

Last month I posted a few tools that analyze your assemblies and provide this information to you.  Definately check these out and look at some of your code metrics to determine what kind of path you’re on and headed down.

This entry was posted in .Net Development, Most Popular, Patterns and Practices. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

8 Responses to Coupling, Abstractness, Stability – Measuring and Applying Code Metrics

  1. Zen says:

    @Tureiti
    The reason the Abstract measure doesn’t make sense is because it is stated incorrectly in the article.
    The abstract measure was introduced (as far as I can tell) by Robert Martin in 1994 (“OO Design Quality Metrics -An Analysis of Dependedencies”) There it is defined as #number of abstract classes / #total number of classes so it should really be A= Na /(Na+Nc). The IBM article you refer to is more or less a rip off of Martin’s paper, with out giving reference.

  2. Ranjan,

    Really not much insight to provide on using Stability. It is really as simple as this:

    The more abstract an assembly is, the more stable it should be. The more concrete an assembly is, the more instable it should be.

    The more stable and abstract an assembly is, the higher in the compile sequence it should be (higher meaning being compiled before other assemblies). The more concrete and instable an assembly is, the further down (compiled after other assemblies) in the compile sequence it should occur.

    Instable abstract assemblies have very little use. They occur deep into the compile sequence of your application and have a high degree of dependence on other assemblies. That is not good use of an abstract assembly. Concrete and stable assemblies exist, especially in data access layers where work is being done. This does not make the assembly useless, but does make it very difficult to make changes to the assembly because so many other assemblies depend on it.

  3. Jeffrey,

    Thanks. I wonder how many people are unaware of the impact analyzing code metrics can have? The metrics I have described above can tell you so very much about the state of your application and how easy or hard it is to build upon and maintain. I hope a lot of people take this information and put it to use.

  4. Ranjan says:

    Excellent article. I hope you can provide some insight on how to use Stability as a metric in real world applications.
    As you said, a concrete stable assembly is going to be an issue, but thats what we are looking for, right? (atleast by the definition, “Stability is measured by determining how easily you can change an assembly without that change having impact on other assemblies within the application”)

Leave a Reply