I think there's a code structuring conflict between extending (or maintaining) the existing functionality and adding completely new functionality.
The best approach for adding new functionality is prototyping - you want to keep everything closer together, separate it from the old code, and fiddle with new stuff until it starts producing what you need. What I noticed about adding new functionality is that you cannot start with overly complicated classes and functions. You get unmotivated and spend days on just trying to figure out how components should communicate with each other. Your productivity can drop by a factor of 10 easily.
So, what I do at start is clamp everything together - mouse handling, keyboard handling, drawing, layouting - all in one function, until I start feeling confident that code does what it suppose to do. But as you have probably guessed, even if you get a productivity boost from this at start, in the long run it can't work. Pretty soon after initial prototyping everything should be subdivided into separate components, with clear cut interfaces between them. This is the only way to make something useful of your prototype code, incorporate it into larger software and start extending it.
So, my question is, is there a way to return to prototyping phase after a large software system has been written? How can you extract useful bits and pieces of the system, in order to construct a single-function-prototype (that will boost your productivity for adding new features)? How can we do it in runtime, for testing parts of the system with easily controllable and isolated prototypes?
EDIT
Just realized just how much my bottom-up prototyping approach contradicts normally used design practices. What they teach in universities is exactly the opposite - you start with uml diagram with 20 classes and use refactoring to fight off over-specification and over-design.