There are plenty of websites and blogs discussing which techniques and methodologies we should use as software developers. When should and shouldn’t we use the Singleton pattern? Should try to future-proof code against possible changes in requirements or should we make sure it only fulfils our immediate needs? Should we write self-documenting code or short and quick to type with explanations left in comments? Which web framework is best, Tapestry or Wicket?

Asking these kinds of questions is a good way to learn about new technologies or techniques you have have not been familiar with and can give you a lot of insight into other parts of the software development world. You can apply some of these pieces of knowledge to broader parts of your job. For example, learning that perhaps using a Singleton pattern was not such a great idea you may decide to review the other parts of your application where you chose a common design pattern over a possible simpler design.

But there is a downside to learning about these new technologies and techniques and that is realising that even if you have a better solution, you may well not have the power to implement it. If you have a well developed web application based on JSF, it’s probably too late to consider using something like Ruby on Rails when you realise it’s better suited to that technology. An established database application based on SQLJ technology is going to be practically impossible to migrate to a much better technology such as Hibernate.

But this is a well known problem in software. You make your choice of technologies at the start of the project. If you need to switch half way through that’s too bad because you’ll just have to pay some high paid consultants to walk you through the process.

Another well known problem is that of technical debt. You write some quick hack to implement a feature or fix a bug as quickly as you can knowing that it could be done better if you just had more time. When you have that time, you tell yourself, you will come back to that problem and implement it correctly. Only that time doesn’t come. And even if it does, well your hacked together solution has been working fine on production for a few weeks now and it hasn’t caused any problems so why bother changing it and risk breaking the same part of the system again?

There are many proposed solutions to prevent the build up of technical debt such as unit testing, code reviews, proper architecture and design meetings, scheduled code maintenance time etc. The problem is there are not many solutions for how to pay off technical debt once you’ve incurred it. In the financial analogy it’s not so hard because you know how often and how much you need to pay back. With technical debt it’s very difficult to measure and it’s even more difficult to pay back.

We come across bad code all the time. “Why didn’t they create a list of objects instead of using a big array” we ask. We could change this code ourselves but it’s too late. The array is used throughout almost all parts of the application. Any change to it now would introduce a big risk or breaking something, or even worse subtly change the behaviour such that it goes unnoticed until it goes live. There are many factors that can make paying back technical debt very difficult. Maybe if we examined them in detail we might find ways to start tackling the task. The worst thing however, is coming up with a great solution to a problem in an application and simply not being able to implement it due to the risk of breaking the entire system.

Something to say?