Steve Smith's Blog

Musings on Software and the Developer Community

Avoid Entrenched Dependencies

Last year I wrote about Avoiding Dependencies and described some Insidious Dependencies (with help from many commenters) that many developers might not immediately recognize as dependencies.  It occurred to me today that I should point out that dependencies themselves are not intrinsically bad design – all software has dependencies.  The important distinction here that I think is a best practice is that one should make efforts to avoid entrenched dependencies on things that are likely to change.

As an example, I write most of my software using Microsoft .NET.  I’m inherently taking a dependency on the CLR.  If at some point the customer’s needs dictate that I need to move to Java or Ruby, that is most likely going to be a painful thing.  However, I don’t foresee such a change being required, so I’m happy to have tight coupling to .NET for most of my applications.

When you perform a code review, whether for your own software or for someone else’s, one of the things you should analyze are the dependencies the code has, and whether these are implicit or explicit and whether they are entrenched or flexible.  If the software simply instantiates classes directly wherever it might need them, and makes no use of Dependency Injection, it’s likely to be riddled with implicit and entrenched dependencies.  On the other hand, if classes identify their dependencies in their constructor via interfaces, and an IoC container is in place to allow easy management of the actual implementation classes that are used at runtime (that conform to these interfaces), then the dependencies are explicit and flexible.  (and on the other other hand, if everything is an interface, the application is likely to be more difficult to understand than necessary – see below)

There are costs associated with abstracting dependencies.  In the extreme, every “new” in your code is a dependency on a particular implementation, and thus could be replaced with an interface and injected in.  In practice, the main things you want to worry about abstracting are the ones that are most likely to change, and over which you have the least control.  Things that need to change in order to test your code count as things that are likely to change, and thus should always be abstracted if you plan on writing good unit tests!  Otherwise, don’t go overboard.  Wait until your dependence on a particular implementation causes pain before you start extracting interfaces and DI-ing them into all of your classes.  All things in moderation.

    kick it on DotNetKicks.com

Tuesday, 13 October 2009

Comments

 avatar

pandora jewellery said on 28 Jan 2010 at 2:22 AM

Otherwise, don’t go overboard. Wait until your dependence on a particular implementation causes pain before you start extracting interfaces and DI-ing them into all of your classes. All things in moderation.


 avatar

indonesian coal said on 29 Jan 2010 at 2:40 PM

The main feature of the software is that If the software simply instantiates classes directly wherever it might need them, and makes no use of Dependency Injection.


 avatar

fetal doppler said on 30 Jan 2010 at 10:36 PM

These two article one introduced last year with the title "Avoiding Dependencies" & and second we can read right now "Avoid Entrenched Dependencies" are best sharing of Steve Smith. The important distinction here that I think is a best practice is that one should make efforts to avoid entrenched dependencies on things that are likely to change.


 avatar

purchase structured settlement said on 02 Feb 2010 at 1:56 AM

But I wanted to point to the actual, original file so that you could see it in all its glory, warts and all, and see how far we’ve come in the last 8 years.


 avatar

The Money System - Step-by-Step Guide to Making Money Online said on 04 Feb 2010 at 7:03 AM

If classes identify their dependencies in their constructor via interfaces, and an IoC container is in place to allow easy management of the actual implementation classes that are used at runtime (that conform to these interfaces), then the dependencies are explicit and flexible.But thank you so much for the explaination with expamples.


 avatar

Zara Clothing said on 04 Feb 2010 at 12:29 PM

The important distinction here that I think is a best practice is that one should make efforts to avoid entrenched dependencies on things that are likely to change.I will continue to read this in future.


 avatar

Ohio State Ladies Jersey said on 05 Feb 2010 at 9:24 AM

If at some point the customer’s needs dictate that I need to move to Java or Ruby, that is most likely going to be a painful thing and i do not think that chabge is need right now as it is going well.


 avatar

background check said on 07 Feb 2010 at 2:55 AM

If the software simply instantiates classes directly wherever it might need them, and makes no use of Dependency Injection, it’s likely to be riddled with implicit and entrenched dependencies. Over all a very nice effort has been done.


 avatar

Tweezerman Nose Hair Scissors said on 09 Feb 2010 at 2:18 AM

It depends whether this would help or not. On larger systems, you should consider this because you may, at a later date, need to determine the user's notification preferences and send them an HTML or text email, or maybe even a twitter or SMS message.Thank you so much Steve Smith> Keep up the good work.


 avatar

Marisol Luna American Girl Doll said on 09 Feb 2010 at 2:58 AM

hat is, for instance, if you are writing an interface instead of using List<T> you should consider using IList<T>. All of the things you listed are examples of concretions that we depend on "Insidious" ly because they are usually provided by the framework and not coded against any abstractions, so it becomes subtle that they are really dependencies.thanks


Leave a Comment

Please join the discussion and share your thoughts.