In John MacIntyre's second blog about Clean Code he presented a very simple little payroll calculator, refactored it, and then asked whether it was truly worth refactoring in an ROI sense. His conclusion was that he would probably not refactor it in a "real" project, but probably would refactor it if it were his own project. His reasoning was that the refactoring was worth doing for artistic reasons, but not for financial reasons.
This argument suggests that Clean Code is about art rather than money. This is a fundamental flaw in logic. Clean code has always been about money, and has never been about art. Craftsmen keep their code clean because they know that clean code costs less. They know that cleaning code has a one-time cost, but that leaving it unclean has a long-term repeating chronic cost that increases with time. Craftsmen understand that the best way to reduce cost and increase ROI is to keep their code very clean.
Here was the code that John began with (I've translated it from C# to Java for my own sanity.)
If we are going to refactor this, we're going to need some tests. So the first thing I did was to write enough tests to cover the code.
The algorithm was a little bit wordy, so I shorted it up a bit and made the two sections of the if statement independent of each other.
Next I got rid of that boolean argument. Boolean arguments are always troublesome beasts. Some poor schmuck is bound to call it with the wrong value, and all the poor people reading this code will wonder whether they should look up the argument to see what it means. Boolean arguments loudly declare that this function does two things instead of one thing.
This had a profound effect on the tests. The tests look almost like they are using two derivatives rather than two instances of the same class. Indeed, we should probably continue pushing the refactoring in that direction. Creating two derivatives is simple enough. First I changed the tests to create instances of the derivatives, and then I wrote the derivaties themselves.
That sets things up nicely. Now I just need to push the calculate method down into the two derivatives.
Nice! Now all I need to do is refactor the two derivatives.
Now that's nice! Nearly the same number of lines of code as the original, and so much cleaner! But was it worth it?
Of course it was! The two business rules have completely decoupled from each other. They are in totally different files, and know nothing about each other. If someone adds a new kind of pay calculation, like a SalariedCalculator, none of these files will need to change! (We call that the Open Closed Principle by the way.) Think about what we'd have had to do with the old implementation! Boolean's don't split into three very well.
Yes, this was worth it. It was worth it because we've all been impeded by bad code before. We all know that bad code slows down everyone who reads it, every time they read it! Bad code is like Herpes. It's the gift that keeps on giving.