Hmm.. was the title intriguing enough for you to check out if you as a developer got any debts to clear (such as that represented below :-)? Well, I am talking about what is called as “technical debt” and that is it. Believe me, there are high possibilities that most of the developers do have technical debts to clear which they (or someone else) introduce in the system while working on it over a period of time. Lets try and understand what/how/why/whens related with technical debt?
As Fowler writes in his blog, technical Debt is a wonderful metaphor developed by Ward Cunningham to help us think about this problem. In this metaphor, doing things the quick and dirty way sets us up with a technical debt, which is similar to a financial debt. Another great article I read on technical debt is titled as the solution to technical debt.
What code/coding approach introduce the technical debts?
Well, code with some of the following code smells add to the existing technical debts:
- Duplicate code
- Long methods (high code complexity)
- Long classes (high code complexity)
- Long interfaces
- Lack of documentation around code
- Difficult to read and understand code (classes and method names)
- Code (classes & methods) with multiple if-then-else (high McCabe’s code complexity)
And, when you quickly want to get started with your application and create something which is demonstrable, you tend to do all of the above, e.g., try and get the functionality done with few classes (long ones), longer methods, and duplicate code. In other words, you introduce the debt to achieve the functionality in quick time. This act introduces what is called as technical debt into the system. However, if these debts are introduced prudently, this gets fixed later in form of dedicated technical debt sprint/releases to avoid several code quality issues in future. The point is that the debt (code smells) yields value sooner, but needs to be paid off (fixed) as soon as possible.
What coding technique do you follow to decrease the debt?
The answer is code re-factoring. In this relation, you may check my blog on re-factoring 3000 lines of code. In brief, you do some of the following to clear off the debts:
- Break down long classes into smaller classes adhering to single responsibility principle; Classes that do just one thing and do it well
- Break down long methods into smaller methods with lesser McCabe code complexity, and for which you could write good unit tests
- Remove duplicate/dead codes
- Rename the methods and classes with self-explanatory names
- Put decent documentation around critical block of codes
- so on and so forth…
In order to understand better, could we categorize these technical debts? Why do they introduced in the system in the very first place?
Lets look at following diagram that I took from fowler’s blog.
Above diagram classify technical debts into following two categories:
- Reckless Debts: These are debts which are same as code smells introduced into the system as a result of lack of knowledge on design patterns or good coding practices, or without much attention to need for adhering to good design & coding practices. These are mostly introduced by less experienced or rookie/newbie software developers.
- Prudent Debts: These are debts which are code smells introduced into the system with the knowledge that it will pay off immediately in terms of delivering the functionality as per the project schedules, and with the belief and plan that these code smells would be removed at later date. These are mostly introduced by experienced developers and that too as a well-informed decision in order to meet the timelines with a note that these debts will be fixed later.
Could we avoid technical debt at all?
Simply speaking, we are living in real world and the answer to the question is a big NO. Lets look at some of the scenarios. As the project (or sprint in agile SCRUM) gets kick started, the developers have got primary responsibility to make sure that he delivers the code of decent quality. Now there are two ways to get your coding done:
- The traditional waterfall way in which you tend to lay down architecture and design, make sure that all stakeholders buy your design and start putting the code around the design. The architecture and design discussions make sure that you have been able to put modules/components with well defined boundaries, and associated functionality. The advantage of this approach is that you put enough due diligence in place to make sure that you functionality is delivered as per an agreed design. However, there is this disadvantage that you may rush towards the end as you may run out of time and, hence, may introduce some hacks here and there. Also, you may not be able to change the code to accommodate any new requirements as this would need design discussions all over again and you just don’t have sufficient time for all this exercises. In this kind of scenario, the chance of introducing the technical debt is comparatively lower assuming the developer is decent with coding skills and that, design is properly laid out. However, developers , at times, choose to incur technical debt to hit an important deadline.
- Then there is this agile approach where you put minimal architecture and design and, get started quickly with coding. In this scenario, to start with, you quickly put some code (mostly dirty such as all code in one or few classes) and get the functionality delivered. Developers actually choose to incur technical debt in the beginning of coding and clear the debts at a later date. Then, as time permits, you go about re-factoring code and reduce technical debt. Thus, you add lot of technical debts in the start of the project or sprint and reduce it gradually as the time permits.
If you look at both the approaches, you may not be able to avoid technical debt to a great extent whichever way you do. However, some developers (experienced enough) tend to have lesser technical debts associated with them then the other ones (rookies/newbies etc) . That said, this blog says that the developers who are unaware of good design patterns, and coding practices may write not a high quality code but these code may not be called as technical debt.