Code Smells: Long Methods
Tags: cleancode, programming, java, javascript
Published: 2024-04-23 19:19:55

## ✅ TL;DR
You should write like a good presenter, use your words wiselly. Follow this rules in your code:

- Extract methods
- Reduce Local Variables and Parameters
- Decompose Conditionals

---
![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExaDM5NzJ4aWJtdjlhbTF0MjcycmZudWMxMHljdXE2d3c3a2xqeWU2aiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/J2gHlRQQvFamqOWlJF/giphy-downsized-large.gif)

## 👃 Code Smells
What is a code smell? Code Smells are the traces in the code that indicates a deeper problem in the application or codebase. It's like the cough that you do when you are sick, it's a symptom. For code, the Code Smells are symptoms for a bad or spaghetti code.

One of this symptom is the Long Method problem.

Imagine that you find this code:

---
## ✂️ Extracting Methods

```java
void printOwing() {
  printBanner();

  // Print details.
  System.out.println("name: " + name);
  System.out.println("amount: " + getOutstanding());
}
```

For some, this is some ok code, but it attracts problems, and it smells bad. It says to me that everything that I need to print, I can just place it inside the `printOwing` method. If you see it like it's telling a story, it's like being wordy, it's saying more than it needs.

"When entering `printOwing` you go to `printBanner` AND print the name AND THEN print the amount + `getOutstading` AND more things that you want to add."

When telling a story, you want to be focused on the main acts, so a better way to do this would be writing the code like this:

```java
void printOwing() {
  printBanner();
  printDetails(getOutstanding());
}

void printDetails(double outstanding) {
  System.out.println("name: " + name);
  System.out.println("amount: " + outstanding);
}
```

"When entering `printOwing` you go to `printBanner` AND `printDetails`"

If the listener wants to know what's in the `printBanner` or `printDetails`, he can ask!

The main thing here is to **extract the method**, much more like being succinct in a conversation.


---
![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExcHRvcGpwYzY5d3h3aWp5bTB3N3dzaTg1NTA2cmJsaWhhbnpvN2I5ZiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/9rtpurjbqiqZXbBBet/giphy.gif)

## ♻️ Reduce Local Variables

If your code requires some variable that's being reused, you should place it in a way it can be reused. It's almost like using synonyms or referencing things implicitly.

```java
double calculateTotal() {
  double basePrice = quantity * itemPrice;
  if (basePrice > 1000) {
    return basePrice * 0.95;
  }
  else {
    return basePrice * 0.98;
  }
}
```

It's using here the same `basePrice`, but it's being repetitive. One way to fix it is doing it like this:

```java
double calculateTotal() {
  if (basePrice() > 1000) {
    return basePrice() * 0.95;
  }
  else {
    return basePrice() * 0.98;
  }
}
double basePrice() {
  return quantity * itemPrice;
}
```

When writing like this, you have a great way to change the `basePrice` if something is changes. It solidifies the code.

It be applied to objects also, if you see things like 

```java
amountInvoicedIn (start: Date, end: Date)
amountReceivedIn (start: Date, end: Date)
amountOverdueIn (start: Date, end: Date)
```

you can change it to 

```java
amountInvoicedIn (date: DateRange)
amountReceivedIn (date: DateRange)
amountOverdueIn (date: DateRange)
```

This is by introducing a **parameter object**. But you can also **preserve a whole object**, like this:

```java
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);
```


```java
boolean withinPlan = plan.withinRange(daysTempRange);
```

Now, if you have this story that the facts are so intricate you can separate part of the story to a different section of you lore. Translating it to code would be like you can try moving the entire method to a separate object via **replace method with method object**.

It would look like we have this code and we cannot extract the price method.

```java
class Order {
  // ...
  public double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // Perform long computation.
  }
}
```

One solution would be to turn it into this:

```java
class Order {
  // ...
  public double price() {
    return new PriceCalculator(this).compute();
  }
}

class PriceCalculator {
  private double primaryBasePrice;
  private double secondaryBasePrice;
  private double tertiaryBasePrice;
  
  public PriceCalculator(Order order) {
    // Copy relevant information from the
    // order object.
  }
  
  public double compute() {
    // Perform long computation.
  }
}
```

As the refactoring guru tells: 
"Transform the method into a separate class so that the local variables become fields of the class. Then you can split the method into several methods within the same class."

---
![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExajQ1dTJ2ZWs2cndxb3B2aDd5N3ppNGkydnYwa2lhYmdyOXpsNmhrOCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/gfl7CKcgs6exW/giphy.gif)

## 💡 Decompose Conditional

This feels like the person that talks a whole story to explain possibilities. Like, dude, I just want to know the possibilities, not the whole lore. That's why in the code when we have something like this:

```java
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
  charge = quantity * winterRate + winterServiceCharge;
}
else {
  charge = quantity * summerRate;
}
```

we change it to:

```java
if (isSummer(date)) {
  charge = summerCharge(quantity);
}
else {
  charge = winterCharge(quantity);
}
```

This way we can be concise and more descriptive. So remember to decompose conditionals.

---
![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExcml4MWl6cmNoanZhcGs0YnBweG11Mjd0NDBsajFjbW1wMXA2ZjRlZSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/aiE3JQU3vLqTK/giphy.gif)

## 📏👍 Rule of thumb
Always remember that in object-oriented code, classes with short methods live longest. The longer a method or function is, the harder it becomes to understand and maintain it. Remember that writing code can be much closer to talking, I mean, so be intentional about your writing.


## 📚 References:
- refactoring.guru