“How did we get into this mess?” you exclaim looking at the code equivalent of:
There are a lot of reasons why projects end up looking like that. Beyond incompetence, there is the realization that you know more about a problem after you solve it.
Here’s a familiar scenario:
You extract an ugly part of a function. Out of the remaining code, you notice that it’s just a special case of a problem you have solved in a more general way elsewhere. A few tweaks later, you remove the special case, a whole bunch of code is gone.
The “Tetris” effect!
A good refactor feels the same way it does when you clear a couple of rows in Tetris. There are insights which allow you to provide the same (if not more) functionality in less code.
I remember reading Refactoring and being annoyed at the series of seemingly trivial changes that were being done to the code. However, one change at a time, the code was getting more and more manageable.
The same is true with Tetris: clearing the first row of block, you can start attacking the second and so forth. Hopefully you reach to bottom.
Which brings another interesting parallel with Tetris: if you don’t start simplifying things and cleaning up your mess, you end up with a big pile of unmanageable code. One block goes on top of another until you touch the top. Eventually, you have to start another game.
Compare that to incoming requirements which result in more features piling on top of each other. At some point, somebody starts talking about doing a rewrite. In effect, that would be like restarting the game. It’s always easier to throw blocks down an empty screen rather than fit them on top of an existing mess.
I’m not blaming anyone … there is a time and place for rewrites. Use judgment.
Can you also think of a time where a new requirement messed up the beauty of the model you had built. Something like this?
The more I think about it, the more I like it.