This is great stuff, thanks for sharing. Tech debt is such a challenging topic and it takes this kind of specific focus to meaningfully combat it. I'd never considered being explicit in the hiring practice about seeing what way a candidate leans when it comes to rewriting components. But I will now.
A couple other ideas I've seen or thought about:
- In startups, embrace the hack. As you start or get into a newer component, if it just seems like it's not going to stand the muster of time without some major follow up work, then lean into it. Explicitly call it out as a component you *will* rewrite in the near feature, treat it as a prototype, and then go as quick and hacky as you can... save cycles now, increase delivery, and then reclaim later by rewriting with learnings you've picked up along the way. Obviously don't do anything that jeopardizes data or critical security, but otherwise, this could save you cycles and improve the overall product over the alternative of trying to salvage and repeatedly shim up initial code.
- Disentanglement - a great way to do this is to either from the start or as part of updates, identifying the clear conceptual component boundaries you want to move towards and then shift to start using contracts and service calls across those components. Especially when a DB is involved, putting an abstraction layer in front of it will really open the doors later for separating/refactoring.
- Customer Pivots - something I've thought about is the idea of inserting an "exit plan" requirement for any prosed pivot. Whatever is in flight gets a quick review to see what it would take to get to a "stable state" (ie, a place where there is no known issues that will require ongoing maintenance). This includes deleting and/or heavily commenting unused code (so a future engineer doesn't revitalize it later without understanding the risks), and identifying any code that is likely to require ongoing maintenance in it's current state. Any issues brought up must either be fixed before pivoting (or in worst case of the pivot being high urgency, filed as bugs with agreement from Product that they will be prioritized ASAP in the first available gap after the urgency of the pivot has been addressed.
- For the transfer of knowledge issues - lean into local documentation. It's easy to want to move to external documents that describe a large system, but they're perceived size can be off putting to make (and thus not happen). But the bigger issue is discoverability and relevance. Where as docs outside of code can become stale (and red herrings), repeated, hard to find (location or search terms), local documentation in the file and the point of relevance. Self describing code or well commented code is sure to be seen when needed and much more likely to be updated as code changes are made. This holds true both for at the function level and component (file) level. There of course are times for higher level architecture docs, but in general, we tend to over index in that direction and should always be placed as "locally" as possible.
- Totally agree on celebrating existing code and not so easily leaning towards rewrites. I know you're comments are in the context of finding the right people and probably don't think all rewrites or suggested rewrites are bad. They do have their place and it seems we also often encounter challenges because we don't have a framework for identifying them. Teams need a process that evaluates estimates of fixing vs rewriting a given set of code against the perceived wins and how well the existing component meets current and known future needs. And when that evaluation is finished, a pattern must exist for making a decision (for the time being) that helps close a conversation and help everyone align on the path forward. Without that, it's hard to have a group conversation on the choice and feel comfortable making a clear call. That leads to frustration, gut declaration of when something needs to be rewritten, disagreement, lost time, poorer choices, and lower morale.
Just my two cents. Thanks for diving into the topic, this post was helpful!
This is great stuff, thanks for sharing. Tech debt is such a challenging topic and it takes this kind of specific focus to meaningfully combat it. I'd never considered being explicit in the hiring practice about seeing what way a candidate leans when it comes to rewriting components. But I will now.
A couple other ideas I've seen or thought about:
- In startups, embrace the hack. As you start or get into a newer component, if it just seems like it's not going to stand the muster of time without some major follow up work, then lean into it. Explicitly call it out as a component you *will* rewrite in the near feature, treat it as a prototype, and then go as quick and hacky as you can... save cycles now, increase delivery, and then reclaim later by rewriting with learnings you've picked up along the way. Obviously don't do anything that jeopardizes data or critical security, but otherwise, this could save you cycles and improve the overall product over the alternative of trying to salvage and repeatedly shim up initial code.
- Disentanglement - a great way to do this is to either from the start or as part of updates, identifying the clear conceptual component boundaries you want to move towards and then shift to start using contracts and service calls across those components. Especially when a DB is involved, putting an abstraction layer in front of it will really open the doors later for separating/refactoring.
- Customer Pivots - something I've thought about is the idea of inserting an "exit plan" requirement for any prosed pivot. Whatever is in flight gets a quick review to see what it would take to get to a "stable state" (ie, a place where there is no known issues that will require ongoing maintenance). This includes deleting and/or heavily commenting unused code (so a future engineer doesn't revitalize it later without understanding the risks), and identifying any code that is likely to require ongoing maintenance in it's current state. Any issues brought up must either be fixed before pivoting (or in worst case of the pivot being high urgency, filed as bugs with agreement from Product that they will be prioritized ASAP in the first available gap after the urgency of the pivot has been addressed.
- For the transfer of knowledge issues - lean into local documentation. It's easy to want to move to external documents that describe a large system, but they're perceived size can be off putting to make (and thus not happen). But the bigger issue is discoverability and relevance. Where as docs outside of code can become stale (and red herrings), repeated, hard to find (location or search terms), local documentation in the file and the point of relevance. Self describing code or well commented code is sure to be seen when needed and much more likely to be updated as code changes are made. This holds true both for at the function level and component (file) level. There of course are times for higher level architecture docs, but in general, we tend to over index in that direction and should always be placed as "locally" as possible.
- Totally agree on celebrating existing code and not so easily leaning towards rewrites. I know you're comments are in the context of finding the right people and probably don't think all rewrites or suggested rewrites are bad. They do have their place and it seems we also often encounter challenges because we don't have a framework for identifying them. Teams need a process that evaluates estimates of fixing vs rewriting a given set of code against the perceived wins and how well the existing component meets current and known future needs. And when that evaluation is finished, a pattern must exist for making a decision (for the time being) that helps close a conversation and help everyone align on the path forward. Without that, it's hard to have a group conversation on the choice and feel comfortable making a clear call. That leads to frustration, gut declaration of when something needs to be rewritten, disagreement, lost time, poorer choices, and lower morale.
Just my two cents. Thanks for diving into the topic, this post was helpful!