Let's say you have a very simple problem: fix a unit or component test that is broken after some major changes in other components. Now, for some reason, a parameter is being passed null and you get a null pointer/reference exception. What do you do?
- You can just to a "if (param != null)" and work around the issue. If this is the only issue, the test be passing, you can close the bug with the feeling that you're quick, your manager will think that you're really efficient, everybody will think that the software is now fixed, and ultimately you will jus collect the rewards for being a good engineer for the business.
- You can try to understand why this parameter is now null, which would require going through some other code, potentially requiring major fixes in some other areas. This will very likely take longer (sometimes much longer), so it will not give an immediate relief to the problem and, depending on your manager, you may be considered someone who is not quick or overengineer or overly complicates things.
- Ticking bomb: essentially that is what this decision is. The code base becomes harder and harder to reason about. Bugs are very complicated to understand, there are side-effects and regressions in my places.
- Time saved with this solution will not be enough for the time investigating issues in the future given the difficulty and obscurity of the software as it has all unclear behaviors. It is just a mess.
- It is just a black hole: the worst, confusing, and less maintainable the code is, the harder it is to isolate yourself from all this mess. To implement new features or bugs, you end up needing to write bad code, because writing good code may require fixing some many other places that becomes very risky to the business and no manager would actually approve that.
- New people changing this code become very scared of making changes, as it may have effects all over the place. In particular in orgs where risk is not reward, but being bold and going above and beyond is not worth the risks you're taking, people will not take the initiatives to improve such code.
- Any serious software professional loses the pride of working on such code base. This is an overlooked and often not even noticed aspect of the hidden consequences of such behavior. You risk losing good professionals and, not only that, but given word of mouth, takes the risk of not attracting really good professionals.
In my experiences, I've come across quite a few people that would pick option 1 right away. And not only that, but it would be very hard to convince them of the reasons to consider option 2. I've seen people from all backgrounds (with and without graduate degrees), working at big and known software companies and at startups. As it turns out, it is a mindset issue, like a friend of mine said. Unfortunately this is one of the areas of the creative process of software development that cannot be enforced by process.
When this is restricted some individuals, it's less of a problem if the team culture embraces high quality - as in, you see people in general improving their code quality and spending time on that, either through additional efforts, reading books or any other material to push themselves forward; management actually values that, etc. In that case, the issue can be contained if the team has the encouragement of rejecting code reviews and the "bandaid" engineers accept comments to fix the issue properly.
However, this issue become very toxic when leads/managers themselves are the first ones to pick themselves (or to encourage through subliminal messages) that the bandaid solutions are the ones to go with. Not only that, but if the company's culture, performance reviews or other mechanisms actually encourage and/or reward one to think in a shortsighted way at the expense of the long-term solutions, then there is nothing one engineer alone can do - and in this case I'd suggest to consider other options. In my opinion, that's where companies start to lose the agility to add features and innovate as they get caught up in the software mess they created in the past.
Finally, do you know what the problem is with the software bandaids that keep getting added to the software? If that software is integral to the business, you can't get rid of it and just do it properly from scratch. Someone will need to deal with the consequences of it. And that's when you distinguish great engineers that are worth keeping in your org: they are not the ones to think that it will be someone else's problem. Great engineers don't think about their upcoming review first, but think about doing it right (of course aligning with the business priorities). If you want to build a great team and a great company, start distinguishing between these types of engineers - not always the ones that apparently deliver are the ones worth keeping or rewarding.
PS - for companies that have surveys among engineer and do take them seriously to improve the company, I'd suggest a couple of questions to measure this effect:
- Do you actually feel proud of the product/service you work on?
- Do you feel that management embraces high quality and does not promote low quality indirectly through shortsightedness?