2 minute read

One day, I was watching another Uncle Bob’s video (yes, they are addictive), when I see one example he gave when talking about open closed principle, it ringed a bell in my head. This looked familiar! The type in some data classes, some switchs or ifs, some &&s and ||s all dancing around in the class. I can almost hear them teasing: “Come and catch me! Come and catch me!”.

I think OK, it’s time to get this fixed.

Now I present you the messy smelly piece of ssssss…..source code as the original design(with some tests amazingly).

version 0

Very easily, we can extract out some functions like isMeal and isOverage.

version 1

Now you may smell feature envy as I did, so let’s move those methods into Expense class.

version 2

Next, replace type with polymorphism, which means create more subclasses of Expense.

version 3

We can now separate printing logic out of the Expense class and into some ExpenseReporter and ReportNamer class.

You may ask, why do we need the ExpenseNamer abstraction, why not just put some getName method into the Expense class.

To anwser your question, consider this: different actors may need different names for the same Expense. The reporter may need totally different names than the UI.

version 4

We are at the end of this fantastic soothing and comforting refactoring session habibi, enjoy life and beautiful code.

comments powered by Disqus