I have been paid to maintain software systems for the last 10 years now. I've rarely started developing a system from scratch, so I guess we could say I've mostly maintained existing systems. This is probably the norm. Also, thanks to the open source movement, I've also seen the source code to at least as many systems I've worked on professionally, and I believe my conclusions still hold for those systems as well.
Managers often push for features first, and quality attributes later. This is understandable, and I don't think changing that focus would be a good idea, except :
- Improving software attributes first (such as speed, reliability, resource consumption, usability, maintainability) might open the door to new features which wouldn't have been possible before. If the system can calculate its results quickly, we may be able to provide feedback to the user quicker, in a more user-friendly way. If its UI is resizable, it may be usable on tablets.
- A lack of focus on the system quality attributes will lead to a costly rewriting from scratch.
I have seen both cases first hand, and often times, because of a lack of leadership in programming conventions, speed standards or testing, programs slowly degrade to the point of having to be rewritten. That's a no-brainer. The new program might have a slightly different feature set, but the development team will have to prove itself to the client and develop quickly, at the risk of having the project cancelled. As a result, quality becomes once again an after-thought. It's something left for the maintenance team to deal with. This vicious circle repeats itself over and over, and good programmers often move on before they can make a lasting impact on the health of the program.
My advice would be to continuously maintain standards in the code as well as in the development lifecycle, and have managers allocate time for working on the quality attributes of the system as well, probably as a percentage of the feature development time. Use that time to
- correct things that have been left for later,
- write unit and integration tests, etc.