Improving Extract Method

Posted November 19, 2014 by Joshua Kerievsky

extractMethodDialogBox

Automated refactoring tools have gotten better and better over the years, yet the pace of improvement seems to have slowed dramatically.

I now find myself living with flaws that I'd love to see fixed.

For example, the Extract Method automated refactoring seems to be unable to do something really basic, like recognize cases of duplicated method calls that simply pass in different values for parameters.

Consider this code:

public void brewForJosh() {
    getBeers("Josh", 3, 27);
    drinkBeers();
}

public void brewForDmitri() {
    getBeers("Dmitri", 4, 30);
    drinkBeers();
}

public void brewForTracy() {
    getBeers("Tracy", 2, 19);
    drinkBeers();
}

Say I highlight the two lines in brewForJosh() above and then select Extract Method:

    getBeers("Josh", 3, 27);
    drinkBeers();

What happens?

I am prompted to supply a name for my new method.

I type in getAndDrinkBeers and tell the tool to do the work.

Here is what I get:

public void brewForJosh() {
    getAndDrinkBeers();
}

protected void getAndDrinkBeers() {
    getBeers("Josh", 3, 27);
    drinkBeers();
}

public void brewForDmitri() {
    getBeers("Dmitri", 4, 30);
    drinkBeers();
}

public void brewForTracy() {
    getBeers("Tracy", 2, 19);
    drinkBeers();
}

Can you see the problem?

Here is what I actually want the tool to give me, automatically:

public void brewForJosh() {
    getAndDrinkBeers("Josh", 3, 27);
}

public void brewForDmitri() {
    getAndDrinkBeers("Dmitri", 4, 30);
}

public void brewForTracy() {
    getAndDrinkBeers("Tracy", 2, 19);
}

protected void getAndDrinkBeers(String name, int amount, int age) {
    getBeers(name, amount, age);
    drinkBeers();
}

In other words, I want Extract Method to understand that code that is identical, except for the value of parameters passed into methods, is duplicated code that ought to be found and replaced by a newly extracted method.

Am I asking too much or is this functionality something we'd expect in our tools at this point in time?