GildedRose Refactoring in Ruby

 



There is dirty code and someone asked you to refactor it.

Where will I start?
What is the aim of refactoring code?
Should I separate some classes and methods?

I am gonna not mention the whole refactoring concept here. I will go by using an example. We will refactor step by step through the dirty code.

Refactor consists of improving the internal structure of an existing program’s source code, while preserving its external behavior.

I am gonna share directly the dirty GildedRose class for now.

You can see everything placed in just one class. We will start to refactor the ‘tick’ method first. As seen, there is a name parameter and we will separate if cases and we can generate some methods using ‘name’ values.

Refactor Step 1 (# separate small methods)

Refactoring Step 2 (# separate small objects)

We generate some methods that cover the ‘tick’ method. And we used case block. But still, everything depends on just one class and we can see still some duplicate calculations.

We need to reach the SOLID principle of at least 3 points :

S — Single Responsibility Principle (every module, class, or function in a computer program should have responsibility over a single part of that program’s functionality)
O — Open / Closed Principle — (software entities (classes, modules, methods, etc.) should be open for extension, but closed for modification)
L — Liskov Substitution Principle (objects of a superclass shall be replaceable with objects of its subclasses without breaking the application)

Refactoring Step 3 — (# separate small objects)

We generated some classes depending on ‘name’ attributes. Will need to change the ‘name’ method.

Refactoring Step 4 (#abstraction of duplication)

Still a lot of duplicates in the tick method and initialize parts. We can see our attributes name are the same as the method name. There is a clue here. We can use the name attr and we can create a subclass using directly the ‘name’ attr. And we can do it in the initialize.

Refactoring Step 5 (#Factory)

Go back to the test.

in the test, we generate a GildedRose instance.
And where is our ‘tick’ method right now? Inside the subclasses. We can directly call the ‘tick’ method from the main class and this method will call the subclass ‘tick’ method.

The ‘item’ will be a GoldedRose instance, like a ‘Brie’ class and we call using the ‘tick’ method for subclass ‘tick’ method.

Refactoring Step 6 — ( #still duplicate)

We have still duplicate code and methods in the subclasses. Let’s generate a common ‘Item’ class. And the Item class will be a superclass for each product.

Refactoring Step 7— ( #making hash, # separate small object)

There is a very common way in the refactoring process. If you call a class almost with the same attributes you can use a Hash method that provides the relative class using the key, and value store.

We have some products in the class and we can put a hash. The key will be the name and the value will be the class instance name.

And we can use directly this hash to create an instance :

Refactoring Step 8 — ( # new methods — new calculation methods)

Right now we can create a new calculation method very easily and we don’t need to change our main logic. That was our goal by following the Open / Closed Principle.

We can see each class and method has just its own responsibility.
That means we caught a Single Responsibility Principle.

What about the Liskov Substitution Principle (objects of a superclass shall be replaceable with objects of its subclasses without breaking the application)

We have the ‘tick’ method in the ‘Item’ superclass. This is the same responsibility for each product. And we don’t call the ‘tick’ method from the Item class. Any subclass that inherits the base class needs to have the ‘tick’ method. The caller can always be sure that the ‘tick’ method is present in the subclass.
Final code :

Hopefully, you have got some ideas and knowledge about refactoring in Ruby from this article. This is not a professional article but might still work in your project.

Comments

Popular posts from this blog

Design a notification system

NETFLIX HIGH-LEVEL SYSTEM DESIGN

URL Shortener System Design