Many people get confused between technical debts and non-functional requirements. Defects can’t be technical debts because technical debts don’t mean not meeting requirements, either functional or technical. Technical debts are related to poor design, poor coding or not applying appropriate design patterns, etc. However, defects are not meeting requirements, and the product is not fit for use or poor performance, etc. Many times these confusions are created by agile doctors (agile coaches). Maybe those doctors are not from a development background or haven’t written a single line of code in their lifetime. They don’t understand the difference between technical debts and non-functional requirements. Not meeting non-functional requirements means there are defects, and those defects can’t be considered technical debts. So below are some examples of both technical debts as well as non-functional requirements. Please read and let me know if you feel I have mentioned anything incorrectly.
What are technical debts?
Martin Fowler has described very beautifully here. But to make it easier to understand, I am adding some examples that I have faced in the past.
I was working on an insurance product in 2007, and we were developing a portal. The actual product was WINS (AS 400), and we were tasked to create a portal using asp.net. Since the backend was AS400, so there was another team writing middleware using BizTalk. The middleware team was developing services, and we were supposed to consume those services to write front-end using asp.net. We started very well, but as time passes, we were running behind schedule. Every time we needed any change, we contacted the middleware team to make few changes in the service layer. Still, they were usually over-occupied with too many changes and taking more time to respond. Since pressure was increasing day by day, the front-end team started bypassing middleware and started pointing to the backend directly to reduce time in fixing defects. We were able to fix defects and delivered them on time. We did maintain a log for all such changes so the middleware team can fix them permanently in the future. Unfortunately, that future never came, but that resulted in increased technical debts because new changes took more and more time to investigate how to fix and where to fix. So basically, we did well initially in launching the portal on time, but subsequent changes took more and more time wherein it was supposed to be taking lesser time as the team was more experienced by then.
In another case with the same product, There were many business rules for generating policy. These rules were driven through XML, and we were using a rules engine. There was a method for policy generation which was linked to the rules engine, and there was a single parameter for that method initially. As development progress, many team members changed due to various reasons. Every new developer has added some more lines of code, but they were afraid to make any changes in existing code due to fear of breaking already working functionality. There wasn’t any good documentation either, and that created more fear among new developers. The result was horrible. The same method was having more than ten overloading methods and more than 100,000 lines of code after 18 months. Nobody tried to refactor code to simplify it. Functionality was perfect, but the code was a disaster. Every time it was talking 2-3 weeks for new developers to understand what was written.
There can be design debts as well, and here is an example. We were developing an EMR application in 2009 using WPF, WCF, and SQL Server. WPF was pretty new, and there weren’t many experienced developers available, but the team still decided to learn and develop. Learning took more time, but still, the team was not very confident about MVVM design patterns, but the business wanted to release it faster. The team moved forward and started building it without having much understanding about MVVM. The result was good, but they wrote code that wasn’t easy to understand and added lots of extra codes that complicated the system. We did similar things with another application using Silverlight at the same time.
Above are not defects but debts. Debts usually get created due to the below reason.
Business pressure: Businesses care about functionality and not about code quality.
Parallel development: When the team tries to meet deadlines by putting more people
Lack of technical skills and knowledge: Not investing enough in learning good practices such as TDD, Refactoring and emergent design, etc.
Lack of documentation: Misconception nowadays due to poor understanding of agile. Where people think agile means no documents or don’t understand the value of living documents
Lack of ownership: This is very common when you outsource your development because, many times, outsourcing companies don’t take ownership.
Poor design skills: Again prevalent when you engage low-cost engineers with less experience
What are non-functional requirements?
As I said above, non-functional requirements are requirements, not technical debts. If pages take more time to open and business complains about it, don’t consider it technical debt. It is a requirement, and not meeting the requirement means defect. The team has to fix this.
Similarly, if the system cannot handle load or error messages are not clear, there are defects, not technical debts.
Below are some examples of non-functional requirements.
Not meeting these means there are defects and not technical debts.
- Data security
- Managing user sessions and securing it
- Server load management during pick hours and non-pick hours
- Page loading time
- Server response time
- Proper log management
- Government compliances etc.
I hope the above will help you to understand technical debt and what not technical debt is. Still not clear, then reach out to me.
Naveen is a Lean-Agile Coach, Professional Scrum Trainer (PST) and Internationally acclaimed Speaker in many Conferences and Agile events. He has over 22 years of experience in multiple domains and he is a Certified LeSS Practitioner (Large-Scale Scrum) and one of the early adopters of DevOps practices and teaches DevOps culture around the Globe.