I've often worked solo, but have been on teams where I've written code that was... not great. Worked, but... suboptimal. Various reasons, but it is what it is. To remedy that, I would try to refactor old stuff in conjunction with new work. That was often rejected. So... I'd take to documenting needed refactorings/fixes in tickets. Those would rarely ever get attention - generally deprioritized or ignored. This led to - for me - constant low-level frustration. When working solo, I can prioritize what I need to; in teams... you can't ever make a suboptimal decision because it will live forever. Or until a 'system is down' moment. Those would lead to "post mortems", in which I would point to tickets requesting to fix ticking time bombs months earlier, explain they were ignored by leadership, and... that came across as 'blaming' or 'antagonistic'. The 'fix' is to just never write suboptimal code, which leads to more frustration and anxiety when writing.
Secondly, in 2017, I got a call to fix something I'd written in ... 2003/2004. That code was still in production (with minor patches by others along the way). It's quite humbling to have to review broken code and corners cut, and realize that you were the one responsible for it (and no one else). That (and a few other incidents) have given me a big change in perspective on writing maintainable code (and documentation, etc).
It depends on the team/company. I've worked on many teams/companies where:
- Developers were encouraged to put in time to maintain and refactor code. (including forcing them to take time to focus on that and do nothing else)
- Engineering-centric work was prioritized over random product management asks.
- Schedules were adjusted to make sure the engineering work is done properly.
I'd say this was my typical experience, including S&P-500 multi-billion dollar companies, 100M-$1B companies, startups. I would also say that in all these cases there were experienced software engineers and managers that could be trusted to make reasonable tradeoffs and also pay attention to business needs. Often engineers interacted/worked directly with customers.
There has to be balance and that balance is typically achieved through people that can apply a balance. Striving for "perfect" can lead to never ending refactoring and never shipping. Ignoring technical debt or shipping garbage can lead to the collapse of the business over time. Neither of these extremes are the right thing. Where exactly you land on that spectrum also depends on the specific product, industry, customers, business.
Joke's on you, our repositories do not live for that long!
But yeah, the experience of having somebody asking you "Hey, you know about X! Do you know anything about this system here? What am I doing wrong that my program always gets a different result?" when it's your code, it's because your code was always obviously wrong, it's the first you ever notice it, and that person's boss is complaining because their code is correct... It's not nice.
"Works but suboptimal" is often an acceptable tradeoff when you have more work than you have time to implement in an optimal way. "Perfect is the enemy of good" and other slogans that MBAs learn in school are phrases you can use when something falls through the cracks.
My phrasing may have been better in some cases. "Works but is going to cause a problem when XYZ happens" may be more accurate. I was actually told by a PM once "how about you just say 'I told you so' after something breaks instead of always complaining about wanting to fix stuff?" which was truly bizarre.
My foodservice days had "if you got time to lean, you got time to clean" drilled in to me, but it's not always the same in software. What constitutes "clean" may be the core issue.
1) You need to foster a culture where those improvements are allowed in
2) Codify norms of how a shared goal is worked on
2a) refactor tests as part of separate PR
2b) realign code with refactoring in mind (this is the begin transaction portion)
3) commit work
4) merge everything into main
It might take 3x longer, but it is more controlled.
The larger the team, or the more consumers, the more important it is to get the interfaces right. And if you can refactor the interface ahead of the code itself, the refactor isn't even noticed.
> in 2017, I got a call to fix something I'd written in ... 2003/2004
We are all time travelers. We are kind to past selves and slightly disrespectful to future self.
Past self - so young, naive but productive! He did so much. At the time it took too long, but looking back, what mountains were climbed! It took me two days to figure out the code, but in the end it was pretty clever. Present self must have bad memory if he forgot it all
Future self - he will right all wrongs. He is older and wiser. He has infinite time. Time to refactor, to replace the XXXs and TBDs with intelligent code. to implement to good ideas and re-implement the mediocre ones.
with better comments, maybe all of them will become one.
I've often worked solo, but have been on teams where I've written code that was... not great. Worked, but... suboptimal. Various reasons, but it is what it is. To remedy that, I would try to refactor old stuff in conjunction with new work. That was often rejected. So... I'd take to documenting needed refactorings/fixes in tickets. Those would rarely ever get attention - generally deprioritized or ignored. This led to - for me - constant low-level frustration. When working solo, I can prioritize what I need to; in teams... you can't ever make a suboptimal decision because it will live forever. Or until a 'system is down' moment. Those would lead to "post mortems", in which I would point to tickets requesting to fix ticking time bombs months earlier, explain they were ignored by leadership, and... that came across as 'blaming' or 'antagonistic'. The 'fix' is to just never write suboptimal code, which leads to more frustration and anxiety when writing.
Secondly, in 2017, I got a call to fix something I'd written in ... 2003/2004. That code was still in production (with minor patches by others along the way). It's quite humbling to have to review broken code and corners cut, and realize that you were the one responsible for it (and no one else). That (and a few other incidents) have given me a big change in perspective on writing maintainable code (and documentation, etc).