The title of this post is a quote of Uncle Bob’s that we hear frequently in the third and fourth Clean Coders episodes. He states that when a function starts to get big it’s most likely doing too much— a function should do one thing only and do that one thing well. Those extra responsibilities that we try to cram into a a long function (aka method) can be extracted out into separate classes.

Yesterday Mike and I worked on the Gilded Rose Kata, which involves adding functionality to a 46 line method that has up to five levels of nested “if” statements… inside a for loop. The method was most definitely doing too much (and looked vaguely similar to some tic-tac-toe code I wrote about five months ago).

The README file for the kata tells you what you should expect the method to do, so Mike had us start out by writing tests to confirm that it actually did it. We wrote twelve tests covering all of the rules, then took a hard look at refactoring the method. Mike made the bold move I was thinking but probably wouldn’t have had the guts to do, and that’s to delete the entire method so we could start from scratch. His reasoning was that our tests would tell us what we needed and we could confidently rewrite the method from scratch.

Although the idea that our tests could be so solid that we could just delete the method that provides ALL of the class logic sounds great, but it still felt like jumping off a cliff into water I know should be deep enough.

Of course, that’s why we make these kind of leaps in practice, and the reality was that the rewrite went quickly and ended up being really clean (with lots of nice refactors from Mike).

And sure enough, as we worked through the tests we could see where the separations in logic were and where the classes were hiding inside the method. We pulled out four separate strategy classes that neatly encapsulated the rules for each type of item we wanted to update. When it came time to add in the functionality that was the original challenge of the kata, Mike added in a few tests and the end result was a small, clean class that only required a few lines of code.