Refactoring Ideas [5]: Behave yourself
It always seems easier to write functional code instead of thinking about objects. It happens to me all the time and probably to you.
Obviously, you need something to remember when and how you can avoid these lengthy if
statements.
I will try to make it clear and for the purpose of making clear enough I am going to use an enum
class instead of a regular one.
After all, we all have come across these long if
s which need a lot of mouse scrolling to reach at the end!
Implementation with code smell
All we need to implement is a program which prints the daily tasks that someone has to do in their job. It sounds simple enough so let’s start coding.
After a couple of minutes coding you may have an example like the one below.
It is short, it uses a method with a descriptive name, it uses enum
class because the days of the week are limited and exact and they are never going to change.
So, it feels that this code snippet is ready to receive more functionality! Let’s add more tasks to our daily schedule then! How about some hobby tasks and shopping tasks?
Let’s see if the code we have already written can be grown in a beautiful way!
Things are getting weird here! The code becomes so lengthy every single time we add a new feature but this might(?) be normal because more features mean more code.
What is, for sure, out of our expectation is that we are doing some copy-paste to implement this switch case. This, violates the DRY principle.
This is not good for any reason. Is there anything we can do?
Refactor before feature implementation
Refactoring is like feeding! You want to go out for a movie in cinema but for sure you have to eat before going anywhere, otherwise you are not going to enjoy the movie with your stomach being in rumbling!
In the exact same way, you cannot enjoy the new feature implementation with some bad legacy code.
Every time that these if
statements come across your functionality try to move the functionality into separate classes.
By moving the logic into your enum
classes you have a very good result.
In the following snippet:
- you can see how easy is to add new tasks into your daily routine
- one day does not need to know the tasks for another day
Even if a new day is going to exist somehow in the future you can integrate it, by adding just one new enum
value in the enum Day
class. Just one line of code for a whole new day functionality!
Leave code better than you found it
Refactoring is a constant struggle between yourself and the code which tends to get rotten. Always leave the code in a better state than you found it.
With this in mind we are going to re-work our previous solution. Can it get any better?
Taking a closer look into the members of the enum Day
and you will observe that we have 3 similar members ( String jobTask
, String hobbyTask
, String shoppingTask
).
The naming betrays your intention, you don’t need String
s here, you need Task
s. If you have variables with similar prefix/postfix always reconsider and start thinking of having a new class.
A lot of data could mean a collection of data
As you probably have seen in the previous code we have 3 similar Task
s. By using the Task
class it became easier to spot the similarity.
So, instead of having variables here and there you can organize them into a Collection
.
The best way to integrate a Collection
into your code is with the Strategy Pattern and make public the functionality that the world has onto your Collection
.
The PostItNote
, below, shows this idea in code:
Rules
The take away rules for this refactoring are:
- Whenever you want to implement a functionality and you need logic based on a class then move the functionality into this class.
- When your variables have the same prefix/postfix name you should create a new class.
- If you are going to need a
Collection
don’t use it directly, do it through a wrapper and export the functionality you need.
More
Do you want to see more refactoring/design ideas? Here is the table of contents.