The Twelve Days of Christmas, Refactored
(aka, A Lesson in Clean Code):

Posted: 2021/12/22

(I took a shot at refactoring a Christmas Song this weekend. Insanely repetitive and predictable, I felt it was high time that someone broke it down. My personal observations and take-aways follow below.)

If there is one thing programmers love, it is clean, DRY (i.e. "Don't repeat yourself"), Object Oriented code.

Is this code always shorter than a quick and dirty implementation, or (Heaven forbid) just banging out text on the keyboard?

Could I consolidate some of the complexity, and scrunch up some of the spacing to make it fewer lines? Yes, I suppose; but then it wouldn't be as beautiful.

So why do we refactor code (besides the fact that it is so much fun)? Well, there are a number of reasons:

1. It eliminates human error

No need to worry about typos or inconsistencies between the 12 verses.

2. It highlights the important parts

Need a quick rundown of which gifts are given? Just check the list of gifts in the "Gift" class here.

3. It is easier to maintain

Need to update the wording of one of the gifts? Just change it one time in the list of gifts.

4. It can save time/effort/space

Want to add another 12 days to your Christmas song? Just pick your gifts and add them to the list.

...and I will then be able to tell my wife that I saved 191 lines of code (348 - 157).

5. It helps to understand the data

A Song is made of Verses, which are made of Lines, in which each Day includes a particular Gift.

NOTE: I did not plan or impose this structure on the code. Rather, I arrived at it naturally by simply solving problems in the code step-by-step.

Summary

Interestingly, the two points that I have argued the most are 3 and 4. Having performed this exercise, however, the point that surprised me and stood out to me the most was the last: It helps to understand the data.

Thus, while it is always nice to be able to demonstrate that you have saved time/effort/space by refactoring (especially to your boss), this is not always the case.

But perhaps that is not the true reason to refactor.

Is there anything else you think I should add? Let me know via Pull Request!