“Remember, code is your house,
and you have to live in it.”
― Michael C. Feathers
"Working Effectively with Legacy Code"
Every project goes through stages. First, there is excitement of design, green-field development, seeing things work. Then there are bug fixes, additional features that may or may not fit the originally designed architecture, little tweaks and changes to accommodate the cases not covered in initial development. And then there is support – making changes based on the usage patterns, keeping up with changing environment, fixing the harder-to-find bugs.
Successful projects go through these stages in a spiral: as time goes on, large sections will get re-written to update architecture, move to a new technology stack, fix the underlying issues of the old code base. And then more bugs will be written, tweaks and updates will be needed and will tarnish the shiny new design, and environment will continue to change.
No matter how many times we’ve been there, for most large successful projects, a large portion of the lifecycle is when the code base is full of slow-moving, bug-prone legacy code that is hard to work on. Eventually, an investment will be made to rewrite or refactor the worst pieces, yet a short while later the development organization finds itself facing the same problems again.
At the same time, developers are being continuously schooled on writing better code, doing TDD, working with legacy code, but all this knowledge turns out to be very hard to put into daily practice.