If you've ever tried cooking a significant meal in the kitchen, then you know things can get pretty messy: pots here, pans there, dirty plates all over because you needed a clean one for this and then another one for that, sink full of different types of utensils... Sometimes it seems like if you want to prepare a good meal, then you're doomed to spending an hour or two after dinner just cleaning up the mess you'll make. But it doesn't always have to be that way.
What if you're a little more diligent with the dishes you use for intermediate steps? Do you really need a clean plate for the cheese you're about to grate or the chicken you're about to tenderize? Or can you reuse one of the other four that are already "dirty" (but not really)? Are you ever at a good "stopping point" where, before moving onto the next step, you can pause and clean up the mess that you've made so far?
Sometimes, if we slow down a little bit and try cleaning the kitchen incrementally as we're preparing the meal, then we can end up with a much cleaner kitchen at the end of the task.
So let's apply this to software.
A lot of ugly code is a result of the author not striving to stay clean. Oftentimes, it's the result of small things that stack up one by one until they reach critical mass and make for a painful experience for the next developer. They're so easy to take care of when they first arise, but so hard to get over when left unattended and given the opportunity to dry and stick onto the rest of the system like old food onto a plate. It is so much easier to clean that plate (or system) when it's still "fresh".
All of this should sound familiar to you—it's called "refactoring," and what I'm preaching here is that you should actively seek out opportunities to refactor your code as you're in the middle of developing features, not just after you're done with them.
In fact, let's take that a bit further, because "seek out" seems like a little bit of an understatement here. Refactoring should be a natural part of your development life cycle, a second-nature activity that you do constantly because it's good for the system and good for posterity.
We've all heard the phrase that a broken window attracts more broken windows. Dirty dishes also attract more dirty dishes because, hey, there's already one in the sink, so I'll just pile this other one on top. It's no different for code. Bad code attracts bad code because, hey, this class is already a bedlam, so I'll just do whatever twisted thing I have to do here and get out.
This blog was originally inspired by bad code that could have easily been good code had it undergone minor refactoring during its inception. No animals were harmed in the writing nor running in production of said bad code.