- As developers we make mistakes - this one is obvious, knowledge about the domain will come with time, the same is also valid for engineering techniques and principles. Until there we are gonna make mistakes and lack of Code Review and design sessions can just potentialize it.
- Pressure to deliver - there are scenarios where we just need make things as faster as we can. Issues in Production that affecting the user experience can be damaging to business. So on this scenarios there is few space to huge refactorings and redesigns and that is reasonable. The problem start when people start use this excuse to put pressure on anything we do, even it is not Production specific.
- Fear to touch on production code - lack of test coverage can make it worst.
- A mix between all them.
Understand the reasons why it happens and learn how deal with them is important for a Software Engineer also. Given the frequency it is scenario is presented to us, know how to deal it sometimes is the key in order to start introduce changes.
The new Bridge Metaphor
Ok, what about rebuild the current bridge in order to attend the new demands? The idea looks promising in terms of costs, but in the end of the day, it'll represent the bridge unusable during days or even weeks, which is unacceptable. Does not matter what happens, people needs to be able to keep using it.
Well, what could be done then? An alternative is keep the old bridge working and build a new one. At some point, when the new bridge is ready, the whole traffic can be switched to the new and fresh bridge disabling the old one.
Even more expansive, this is the most feasible thing that can be done once the other approach would bring several headaches to the users
Ok, but what it is the relationship with software development? I'd say it is all.
Business needs to keep moving, most part of the time there isn't much space to stop deliver functionality to make big redesigns. Try to sell this approach to business usually does not work. Moving things little by little is much easier to sell once it can be conciliated with functionality being delivered to production. This is like keep the old bridge working while new one is being built, as far you can see on the picture.
As a Software Engineer, I usually spend most part of my time maintaining software rather than working on green field projects On such scenarios i have been following this approach in order to delivery good software and keep things moving. It also fits pretty well when dealing with legacy software.
The downside when following this metaphor is that at some point you will need to accept some code replication and some "ifs" on the code being delivered while the new bridge isn't done.