Every developer knows what code smell is. I also thought I knew. But it is not just looking at code and saying "this code seems bad". Code smells are a really documented topic with solutions to each problem, since 1999 and this book from Martin Fowler and Kent Beck. This article is part of a 23-Day Challenge on learning code smells and how to avoid them.

Long Parameter List

Today, let's learn a little bit more about the "Long Parameter List" code smell. It is pretty easy to understand : when we have more than three parameters in a method definition, maybe there is an object hiding and sleeping somewhere zzz

Wait... why is it bad ?

Because long parameter lists are hard to understand, they become difficult to use and inconsistent, and because we are always changing them as we need more data.

Let’s use an example of a method with a long parameter list :

def shop_definition(title, size, revenue)
  "#{title} has a size of #{size}ft2 and a revenue of #{revenue}"
end

shop = Shop.new(title: "Zara", size: 20000, revenue: "$16B", current_discount: 30)
revenue = shop.revenue
size = shop.size
title = shop.title

shop_definition(title, size, revenue)
# => "Zara has a size of 20000ft2 and a revenue of $16B"

The really bad thing here is that we cannot add another characteristic to our method without changing the method call in every places it is used.

Preserve Whole Object

In a lot of cases, we have three or four parameters because there is an object hiding somewhere. So instead of passing multiple parameters, we can preserve the whole object and directly pass the object as a parameter in the method.

For this example, I choose the « Preserve whole object » solutions, but there is other ones like « Replace parameter with method » or « Introduce parameter object », depending on the situation.

Let’s refactor our old method by passing the whole object instead of multiple parameters :

def shop_definition(shop)
  "#{shop.title} has a size of #{shop.size}ft2 and a revenue of #{shop.revenue}"
end

shop = Shop.new(title: "Zara", size: 20000, revenue: "$16B", current_discount: 30)

shop_definition(shop)
# => "Zara has a size of 20000ft2 and a revenue of $16B"

What is awesome is that now we can add data without changing any method call. So we won't risk to break anything if we decide to add something to our sentence, because we trust the shop object to behave like a Shop instance :

def shop_definition(shop)
  "#{shop.title} has a size of #{shop.size}ft2, a revenue of #{shop.revenue} and its current discount is #{shop.current_discount}%"
end

shop = Shop.new(title: "Zara", size: 20000, revenue: "$16B", current_discount: 30)

shop_definition(shop)
# => "Zara has a size of 20000ft2 and a revenue of $16B and its current discount is 30%"

Great, so we have seen what are the benefits of reducing our parameter list by directly passing an object. I hope this helped !

Always keep learning earth_americas

#code smell #refactoring #ruby #ood