Quickly check for duplication with your IDE refactoring tools

| 3 min read

This week, I was looking at some code that I suspected contained duplication, presenting a good refactoring opportunity. I wanted to know if I could eliminate the duplication in the multiple conditionals, or even go a step further and consolidate the conditional logic in one place, where I could edit it to make it simpler.

Here is that code:

public function getDataAboutSomething(ASomethingId $somethingId): DataAboutSomething  
{  
    // Some other code  
  
    if ($draftEloquent) {  
        if ($draftEloquent->validation) {  
            $draft = new PieceOfData(false, true, $draftEloquent->validation);  
        } else {  
            $draft = new PieceOfData(true, false, $draftEloquent->validation);  
        }  
    } else {  
        $draft = new PieceOfData(false, false, null);  
    }  
  
    if ($preMarketEloquent) {  
        if ($preMarketEloquent->validation) {  $preMarket = new PieceOfData(false, true, $preMarketEloquent->validation); } else {  
            $preMarket = new PieceOfData(true, false, $preMarketEloquent->validation);  
        }  
    } else {  
        $preMarket = new PieceOfData(false, false, null);  
    }  
  
    if ($deliveryEloquent) {  
        if ($actableEloquent->validation) {  
            $delivery = new PieceOfData(false, true, $deliveryEloquent->validation);  
        } else {  
            $delivery = new PieceOfData(true, false, $deliveryEloquent->validation);  
        }  
    } else {  
        $delivery = new PieceOfData(false, false, null);  
    }  
  
    if ($archivedEloquent) {  
        if ($archivedEloquent->validation) {  
            $archived = new PieceOfData(false, true, $archivedEloquent->validation);  
        } else {  
            $archived = new PieceOfData(true, false, $archivedEloquent->validation);  
        }  
    } else {  
        $archived = new PieceOfData(false, false, null);  
    }  
  
    return new DataAboutSomething($draft, $preMarket, $delivery, $archived);  
}

By now, you probably notice the duplication too and are thinking about how to refactor the code.

But, should you trust your eyes completely? Initially, I trusted my judgment and moved forward with the code. However, let's pause for a moment here.

How can you be certain it's truly duplication?

Searching for one occurrence to match it with others isn't effective, as the variable names are different. You could use a regex search, but it's not straightforward, especially if the indentation varies (as I intentionally did in one of the occurrences).

So, you're left with meticulously reading the code.

Or...

Do you speak French and want to stop hating your tests ?

I've created a course to help developers to improve their automated tests.

I share ideas and technics to improve slow, flaky, failing for unexpected reason and hard to understand tests until they become tests we take joy to work with !

But you'll need to understand French...

You could proceed as I did: try extracting a method and rely on your IDE to handle it correctly. If the code is essentially the same, except for variable names, the IDE will extract the method and offer to replace all occurrences of the duplicated code.

This approach worked, except for one instance. If you examine closely, you'll notice that the variables in the two if conditions aren't the same. Did you catch that initially? I didn't.

Here is a gif of the process:

A demo of the refactoring and the discovered non duplicated fragment.

Without the IDE, I might have inadvertently altered the logic of the code. The IDE revealed that what I thought was duplicated four times was actually only three. This discovery led me to discuss the inconsistency with my coworkers, who suspected it was likely a bug and should have been coded like the others.

So, I uncovered a bug by leveraging my IDE's automated refactoring tools and being somewhat lazy.

Additionally, the IDE, by analyzing the syntactic form of the code, recognized that the second block, despite its irregular indentation, had the same meaning as the method I extracted.

Dealing with legacy code often uncovers insights when experimenting with refactoring tools. Try things out, see where it leads. If you're not satisfied with the results, you can always revert the changes. Assess if the refactoring aligns with your expectations. It's an effortless and risk-free approach.

When you spot potential duplication in code, try extracting a method. See if the IDE applies the extraction in multiple places or not. You'll gain insight. And who knows, you might just eliminate the duplication with a few keystrokes.

Cleaning some legacy code is intellectually rewarding; it can even be fun when you use your automated refactoring tools, not to mention that it greatly reduces the risk of mistakes. If you need some help to get started or to deal with your legacy codebase, let's chat and see how I can help.