I remember a moment a few years back where a client asked me to make a minor modification to an app I'd built for them a few years before. I'd not touched the app in a long time, it had just been happily running in production and I'd moved on to other things.
When I came back to it, I was blown away. This was some of the nicest, well-structured code, I'd ever written. It was easy to read (as easy to read as code can ever be), all the pieces slotted together nicely and the test suite was easy to understand and functioned not only as automated testing - but, more importantly, as documentation on how to use the system.
However, this is a rarity.
Normally we come back to our old code and we look at it in disbelief.
"What was I thinking?" "How could I have been so naive?" "Oh my, I'd forgotten I used to do things that way, what an idiot I was!"
This is actually a really good thing.
It means you've grown. You've learnt. Current you is a better developer than old you.
In this case, I think the fact that the app had been untouched in so long probably made things better - because when you're in the thick of it, with change requests flying in and so much of it being "URGENT", it's easy to take the easy route and do the quick change, rather than sitting back, pausing for a minute and thinking it through.
Even now, with Collabor8Online, which in lots of places is some of the best code I think I've ever written, I come across stuff I wrote last year and want to rip it out and rewrite it, using the new patterns I've implemented and the lessons learnt from seeing C8O actually being used by real people.
Because of this, we've got a whole stack of tickets tagged as "internal" and they keep getting pushed back in the queue as customer requests, or things that demo well and help bring in sales, get prioritised.
So how do you deal with that? How do you make sure your pristine codebase doesn't turn into a stinking mess?
Every week we do a quick review of the tickets that are still outstanding and try to reorder them - again, based mainly on what customers are asking for.
But when I pick one to start working on, I also go through my "internal" tickets and see if there are any that are in a closely related area. If there are, I'll pick that as well, and do the two pieces of work as one feature.
Because ultimately we need the features to keep existing customers happy and bring in new ones. Without that revenue, I wouldn't have a job for very long.
But with every change I make, I try to leave it, and the surrounding code, just a little bit better than when I found it. It's a never-ending task, but nothing's ever perfect; there's always room for improvement.