Overtake Technical Debt: Make Your Code Invincible
Anil Kalose
Over 20 yrs of accelerated general mgmt experience in the Process Quality Assurance. Having directly led a team of over 30+ associates and budgets ( P&L ) in excess of $20 million.
Continuous Reviews for Clean Code Delivery - I
Continuous Reviews for Clean Code Delivery - II
"Code Metrics bugs, security, quality index, reliability, and few more show my code is good. But still when I fix a defect, fix is breaking some of the old defect fixes". Of course, a bad fix can break the old fixes as well. But here it is not the case. Here it is a clear sign that code is plagued with technical debt. This debt is very bad and compounds over time if unchecked and actioned at regular intervals. Affects performance. Getting way completely of the technical debt maybe not possible, but it is important to have a manageable debt in the code. Technical debt also ensures turn around of the fixes will be faster compared to fixes with high technical debt for the same code.
In another scenario, let us assume you are adding new code, new features, and not fixing the known defect. As new code is added, if it starts to take more time than estimated for the feature to complete or more and more unexpected defects are popping up delaying the feature development further, it means the technical debt is high in code and needs immediate attention.
The term "Technical Debt”, first defined by Ward Cunningham and is a business concept heavily promoted, as an effective method of valuing negative equity in software.
Technical debt (also known as design debt[1] or code debt, but can be also related to other technical endeavors) is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy (limited) solution now instead of using a better approach that would take longer.
This is usually measured in "hours" taken to fix the bad code. A wide variety of ways to define and calculate Technical Debt are emerging.
Is it necessary to fix the technical debt?
Technical Data is usually thought of as a bad thing that needs to be paid down ASAP or avoided as much as possible or altogether, however it is unavoidable. Just like financial debt there is a no-good technical debt, but there is technical debt that one can deal with.
The developer can start coding with his understanding of the requirements. The goal is not writing perfect code in the first attempt, the goal is to reduce inefficiencies in the code as and when developers get more clarity on the requirements.
How technical debt creeps in? [2]
It happens when requirements are not understood holistically or from the Product Manager's perspective. Also by not designing the product rightly, By not following the coding standards, By not doing code reviews to detect the real violations/issues, More important is time pressure what makes it unavoidable either through quick/short cut for fixes or immediate delivery and postponing the overall quality. Unreadable code, duplicate code, builds failing are a few more reasons.
- Insufficient up-front definition, where requirements are still being defined during development, development starts before any design takes place. This is done to save time but often has to be reworked later.
- Business pressures, where the business considers getting something released sooner before the necessary changes are complete, builds up technical debt comprising those uncompleted changes.
- Lack of process or understanding, where businesses are blind to the concept of technical debt and make decisions without considering the implications.
- Tightly-coupled components, the software is not flexible enough to adapt to changes in business needs.
- Lack of a test suite, which encourages quick and risky band-aid bug fixes.
- Lack of documentation, where code is created without supporting documentation. The work to create documentation represents debt.
- Lack of collaboration, where knowledge isn't shared around the organization and business efficiency suffers, or junior developers are not properly mentored.
- Parallel development on multiple branches accrues technical debt because of the work required to merge the changes into a single source base. The more changes are done in isolation, the more debt.
- Delayed refactoring – As the requirements for a project evolve, it may become clear that parts of the code have become inefficient or difficult to edit and must be refactored in order to support future requirements. The longer refactoring is delayed, and the more code is added, the bigger the debt.
- Lack of alignment to standards, where industry-standard features, frameworks, technologies are ignored. Eventually, integration with standards will come, and doing so sooner will cost less (similar to 'delayed refactoring').
- Lack of knowledge, when the developer doesn't know how to write elegant code.
- Lack of ownership, when outsourced software efforts result in in-house engineering being required to refactor or rewrite outsourced code.
- Poor technological leadership was poorly thought out commands are handed down the chain of command.
- Last-minute specification changes, these have the potential to percolate throughout a project but no time or budget to see them through with documentation and checks.
How can we manage it while continuing to meet customer needs and pushing features out [3]
Refactor
This is like paying back the principle. Refactor design, refactor code quite often. At regular intervals in a project, plan to dedicate some time for refactoring. if in agile, set up two or three weeks of dedicated refactoring in each release. You can also view it as an investment for which benefits can be realized for sure in multi-folds at a later time.
Code Smells
One needs to keep a tab on code smells. Remove the unwanted pieces of code early. Early meaning, as soon as it is introduced. There are tools where you can baseline the quality of code and track for the new issues entered from a particular point in the life cycle. This is an input to know if one has introduced new code smells and helps in taking action to remove. One has to remove the newly introduced code smells but also put the effort in removing the existing code smells, gradually. There are multiple tools, that give this info and leverage from it and reduce the code smells.
Keep it simple
Keep the code simple and design simple as much as possible. Don't try to anticipate the future needs and code in advance or design in advance. Don't confuse this for scalability. Don't guess the future requirements unless the possible future requirements are known in advance. Don't assume else discuss with the team about your assumptions and let everyone know about the intended purpose of the new complexity you are introducing. Maintain good enough documentation for future reference by the team.
Dependency
Try to keep the user-stories or the code independent or minimal dependency.
Selection of reviewers
While code review is important, and whom you chose to review the code will improve the overall quality and now out interest is technical debt for time being. Reviewers are not necessarily seniors always, in fact, it should be developers whose code will be impacted because of your code. Choose 3-4 reviewers and close the review when you get feedback from at least two of them. For more on code reviews check "Continuous Reviews for clean code deliver".
Pressure on Timelines
One of the major causes of technical debt is scheduling. If a developer is given a tight schedule to complete a large feature they'll have to cut corners they can to get that system delivered on time and those choices made will be hard or even impossible to undo. Manage the time pressure, makes technical debt unavoidable.
Automate
Automate the reviews, automate the test, and ensure the test coverage is high, be it unit testing or regression testing. Have check-in rules and ensure for every check-in it is met and signed off before the code is checked. One of the examples - in Git the pull requests have to be clean and signed off and at-least it is reviewed by minimum reviewers.
Metrics
Measure maintainability and changeability and take action to improve it.
Dynamic Code Analysis
If you have a choice or the option to use dynamic analysis tools, do integrate them with IDEs and ensure you look into the issues which tool throws dynamically.
Meaningful comments in the code
Provide comments in the code. Don't make this one or two-word comment. Rather give what is a piece of code is expected to do in "present tense". Developer finds in their chaotically arranged code as soon as other people start to work on it. Well, let's just say they can't and the same is true of poorly commented code or disorganized assets organizing everything at this late point could take someone hours or days or even weeks.
Technical debt is similar to financial debt and if it isn't repaid in time, it continues to compound until the principal ends up being much higher than the original. In development terms, a problem can grow and grow without anyone noticing until it's too late or too large to fix. The decision to fix an issue right away or leave it until later is something that every oner or every team has to deal with - it's a trade-off early on while getting new code working quickly.
Benchmark Estimate: Based on the technical debt definition and analysis of 1400 applications containing 550 million lines of code submitted by 160 organizations, CRL(CAST Research Labs) estimates that the Technical Debt of an average-sized application of 300,000 lines of code (LOC) is $1,083,000. This represents an average Technical Debt per LOC of $3.61
In a project, while one starting out these errors tend to get overlooked because they aren't seriously blocking anybody from getting any work done, everyone assumes they'll get it fixed at some point or that someone else will deal with those issues down the road or no one knows how to solve these errors and project needs to keep moving on. To other tasks, this is a problem because the cost of redoing any of that work might be exponentially more expensive during the later stages of development.
Many systems may rely on buggy code. A simple fix that would have taken a developer about a few minutes, in the beginning, could potentially cause no longer function at a point, requiring weeks to find the bug. Even the developer that coded in the first place maybe isn't on the team anymore. All this could cause hours or days of wasted production time and to top it off sometimes these things don't immediately occur to people as problems.
Adopt techniques and strategies to overcome the technical debt issues. However, sometimes you need to incur technical debt in order to get a product out to market quicker and even the refactor might help sometime. You realize that technical debt is unavoidable. Hence it is important to look at ROI and decide what to do with technical debt, either getaway or live with it. discuss with the team, discuss with Client on consequences of not having dedicated time for technical debt now, will only mean that it consumes more time in the future.
And the best thing is, you build it into product strategy, in product road-map and there are ways of being able to manage that technical debt at a good pace so that you never have to end up with having to do a huge re-work.
Thank You.
References:
ttps://martinfowler.com/bliki/TechnicalDebt.html
https://dzone.com/articles/technical-debt-amp-scrum-who-is-responsible
https://www.castsoftware.com/research-labs/technical-debt-estimation
Solution Lead/Cloud Architect/Solution Architect
4 年Its nice summary of things to fallow as a standard approach for a quality product, One more thing to add maintaining a simple structure of the code to maintain to produce quality product in less budget..