When is it a Good Idea to write Bad Code?
Imagine an asteroid is barreling towards earth and the head of NASA tells you and your development team that they have 12 months to code the guidance system for the missile that will knock the asteroid off it’s earthbound trajectory.
Your first thought may be, “Sh$@*t!” But let’s say you agree. What does the quality of your code look like after 12 months? Is it perfect?
Now imagine an asteroid is barreling towards earth and you have only 1 month to code the guidance system. Now, imagine a worse scenario, you only have 24 hours to code the guidance system or the earth is a goner.
What is Technical Debt?
You should read Martin Folwer’s excellent introduction to technical debt. Technical debt could be defined as the difference between the application that you would like to build and the application that you actually build.
All software projects with limited resources will accumulate technical debt.
Technical debt is often viewed as a negative or pejorative term. However, in reality, technical debt can be leveraged to actually launch successful applications and features. The key to leveraging technical debt is to understand:
Application development typically involves a variety of groups and individuals, for example the development team, business stakeholders, and your end users. To understand technical debt, it’s important to realize the following:
Technical debts are always paid by someone.
Types of Technical Debt
To understand technical debt, it is important to understand the different types of technical debt that can accumulate in an application.
Missing Functionality
Missing functionality can make the user experience of your application more awkward to use, but on the up side it doesn’t pollute the codebase. Chopping features can be a useful technique for reaching deadlines and launching your application.
Tradeoffs
Broken Functionality
Broken functionality refers to code that “straight up” does not work under some or all circumstances.
Tradeoffs
Bad Architecture Design
Systems benefit from being loosely coupled, and highly independent. Conversely, highly coupled systems with lots of dependencies or interdependencies can be highly erratic and difficult to maintain and upgrade. They can also be very difficult to reason about.
Bad architecture decisions can be some of the most expensive to fix, as architecture is the core underpinning of your application.
Tradeoffs
Bad User Experience Design
If you’re users don’t know how to user your application or make mistakes while using your application because of an overly complex user interface, than it will surely be your user base that is paying down this form technical debt.
Bad user experience design can be very expensive to fix since the whole of the application development process depends on it. Leaving the very real possibility that you’ve spent your limited development resources creating subsystems and code that don’t properly solve the problems of your end users.
Tradeoffs
- Decreased utility as your users struggle to fully take advantage of the application.
- Very complex refactorings, since user interface inherently tend to be highly coupled, so again more possible drag on future development.
Lack of Testing
The main purpose of testing, both automated and manual is to answer the simple question, does your code work? If you can’t answer this question, then you’d be better off heading to the casino rather than launching your application.
In a lot of ways, “lack of testing”, can be viewed through the lens of understanding what you’re application is capable of.
Tradeoff
Bad Code Readability
This is usually referred to as code smell, and again I like Martin Fowler’s explanation. Bad code readability is easy for a developer to spot, because they simply look at the code and decide if it makes sense to them or not. Therefore it can also be subjective.
Being able to read and understand code is critical to being able to debug and modify it later. This should not be confused with broken functionality, which is a different concept.
In developer circles, there is a somewhat innate bias towards overemphasizing this form of technical debt (the reason being that it is the developer, that will ultimately pay for it). Just remember that you can have “Bad Code” that doesn’t smell (silent but deadly).
Tradeoffs
All applications will have some level of technical debt in each of the above categories, but again, it is in managing this debt that gives a development team the ability to successfully launch their application.