Raymond Lewallen

Sponsors

The Lounge

Wicked Cool Jobs

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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.


Posted Fri, Jul 15 2005 10:36 AM by Raymond Lewallen

[Advertisement]

Comments

Jeffrey Palermo wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Sun, Jul 17 2005 10:28 PM
Awesome!
Ranjan wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Mon, Jul 18 2005 2:09 AM
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")
Raymond Lewallen wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Mon, Jul 18 2005 6:47 AM
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.
Raymond Lewallen wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Mon, Jul 18 2005 6:52 AM
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.
Darrell Norton wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Mon, Jul 18 2005 8:21 AM
Very nice.
Raymond Lewallen wrote Introduction to Refactoring
on Mon, Jul 18 2005 11:58 AM
A beginner's look at refactoring, and 4 major design pitfalls to look for.
Robin Curry wrote Code Metrics and Code Metrics Tools
on Fri, Jul 29 2005 2:36 AM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Mon, Aug 1 2005 11:17 AM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Fri, Aug 26 2005 5:34 PM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Fri, Aug 26 2005 5:43 PM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Sat, Aug 27 2005 10:25 AM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Mon, Aug 29 2005 9:49 PM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Mon, Aug 29 2005 9:51 PM
Robin Curry wrote Code Metrics and Code Metrics Tools
on Mon, Aug 29 2005 11:14 PM
Test Early » Boiling frogs and code metrics wrote Test Early » Boiling frogs and code metrics
on Sun, Jan 7 2007 8:57 AM
Tureiti Keith wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Sun, Oct 5 2008 6:10 AM

Hi,

Great post! I have a question regarding the abstractness measure. I see that at <www.ibm.com/.../>, abstractness is described as "the ratio of abstract to concrete classes"; exactly as described in this article. The expression "A = Na / Nc", given above, is said to give A a range of zero to one inclusive. However, if an assembly contains more concrete than abstract classes, Nc > Na, and therefore A > 1. In fact, as Nc approaches zero, A approaches infinity.

Does the abstractness measure assume that Na <= Nc (i.e. an assembly will never contain more abstract than concrete classes)?

Thanks,

Tureiti.

Why POCO is well implemented and designed? « CppDepend wrote Why POCO is well implemented and designed? &laquo; CppDepend
on Thu, Sep 24 2009 7:28 AM

Pingback from  Why POCO is well implemented and designed? « CppDepend

Zen wrote re: Coupling, Abstractness, Stability - Measuring and Applying Code Metrics
on Mon, Dec 7 2009 6:31 AM

@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.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us