Feb 10, 2009

Should I Decouple My Code?

If you look around the internet you’ll find lots of information on refactoring your code, making it more testable, improving its maintainability, and using DI/IoC techniques to increase the ease in which you can make changes to it.  A very large element in all these subjects is having code that is loosely coupled and learning how to take existing tightly coupled code and improve it.

That’s great…. and making these changes is a laudable goal, but what do you do when you look at the code you work on each and every day and you see how tightly coupled it is and then look at just how many more changes and features your customers are asking you to add and make to your application.  You know you want to clean things up to make it easier to get through that backlog of requests but when is it right to decouple and when is it OK to leave code as is?  It’s a valid concern and was asked as a follow up to my screen cast on Decoupling Your Code by Example.

So first, let’s be clear; tightly coupled code is a form of technical debt that will decrease your ability to quickly and cleanly make changes to an existing code base and thus slows the rate at which you can get through that backlog of customer requests.  And since those customers making the requests are in all likelihood the same ones that end up paying your wages then it’s probably a good idea to go as quickly as you can.

OK, fine; but now let’s consider the agile principles of not wasting effort and delivering business value to the customer as quickly as possible. If we have an existing code base that is full of tight couplings then we can’t very well ask our customer for x-weeks of time to let us refactor the internals of the application to reduce coupling.  It’ll would add zero business value to the customer because in x-weeks we would have delivered zero new functionality.  We would also very likely be changing parts of the application that are not going to see any changes in the future – thus it would include wasted effort.

It’s therefor pretty logical that we really only want to decouple code when we’re actively changing it.  We should apply the boy scout rule and “leave the campsite better than we found it”, or in our case, the code base.  Also, we don’t want to go fixing stuff up that we aren’t currently changing, no matter how ugly it is or how tempting it is to improve it – if we do we are only slowing down our development efforts on the items we need to be delivering now, items which our customer is expecting.  In doing so we also run an increased risk of introducing new bugs.  Why? Well, if we only have a certain amount of time to finish something then we really don’t have enough time to do a proper clean up of things outside of the area we are currently working on. So we’ll probably do what most of us do when time is short; make a change that we think is OK (but isn’t) and we won’t worry too much about the tests.

The agile principle of wasted effort can also come into play when looking at coupled code in an area of the application we are actively changing.  Some tight coupling just isn’t worth the time and effort to change.  Let’s say we have a tight coupling to ADO.NET which makes our code a bit clunky in places. It’s awkward at times to use and we could be faster if we changed it, but is it really worth x-weeks to rework our code to use an improved data access mechanism just so we can have a more loosely coupled design? Is there enough payback in making that change that it benefits the customer directly, or even indirectly by saving us more than x-weeks worth of effort further down the track? Maybe; maybe not.  In most cases probably not.  And if the payback isn’t there, then don’t make the change.

So, should you decouple your code?  The answer is, like all things in software development: it depends. These two questions can probably help you make that call.

  • Is the decoupling in an area of the system I’m currently working on?
  • Will the time spend changing the code more than pay for itself with time savings later?

If you can answer “Yes” to both of those, then it’s probably time to decouple your code.  If you can’t, then get on with giving your customer what they asked for – new features in their application.

3 comments:

  1. Agreed, this is the same approach I've been preaching for awhile now, wish I had thought to blog about it =]

    ReplyDelete
  2. I like the metaphor of "every once in a while restaurants should do their dishes to stay in business"

    on past projects I have had explicit refactoring "timeouts" every 3-5 iterations. These timeouts would typically be one week.

    While real-time refactoring is ideal, sometimes the pressure to deliver just gets in the way. Having a timeout allows the team to make sure that they keep technical debt manageable.

    Jeff

    http://agileconsulting.blogspot.com

    ReplyDelete
  3. @Jeff. How do you sell that timeout to management when the pressure is on to deliver? A one week pause while everyone cleans up seems like it could be a hard thing to get buy in from PO for.
    And what would you do if you were doing a shorter project, say 2 months, with only 4 iterations?

    ReplyDelete