mins
mins

Reputation: 7524

Refactoring in Eclipse/Java: Apply "Extract Method" (Alt+Shift+M) afterwards

I wish to know if this is possible to replace some code by a call to the method extracted earlier.

For example, I have a class with similar patterns:

public class ExtractMethodDemo {
    public void doSequence() {
        long n1; n2;
        // Compute and print count
        n1 = 70;
        n2 = compute(n1);                                        // <-- 1st
        System.out.printf("Input %4s, output = %s.%n", n1, n2);  // <-- occurrence
        ....
        // Compute and print count again
        n2 = n2 % 100;
        n1 = compute(n2);                                        // <-- Nth
        System.out.printf("Input %4s, output = %s.%n", n2, n1);  // <-- occurrence
    }
}

I refactor using a method but for some reason some occurrences are still not refactored (possible if Replace additional occurrences... is unchecked, or if same code is pasted later):

public void doSequence() {
    long n1; n2;
    // Compute and print count
    n1 = 70;
    n2 = doAll(n1);                                          // <--- method extracted
    // ....
    // Compute and print count again
    n2 = n2 % 100;
    n1 = compute(n2);                                        // <--- oops! this one is
    System.out.printf("Input %4s, output = %s.%n", n2, n1);  // <--- still old style
}

private long doAll(long n) {
    long n2; // (BTW: not the n2 declared in doSequence!)
    n2 = compute(n);
    System.out.printf("Input %4s, output = %s.%n", n, n2);
    return n2;
}

Is it possible to have reamining sequences refactored afterwards:

public void doSequence() {
    long n1; n2;
    // Compute and print count
    n1 = 70;
    n2 = doAll(n1);
    // ....
    // Compute and print count again
    n2 = n2 % 100;
    n1 = doAll(n2);    // <--- would be great to apply same refactoring afterwards
}

Upvotes: 1

Views: 173

Answers (1)

Carl Manaster
Carl Manaster

Reputation: 40356

Maybe a tiny bit better than re-inlining the code would be to Extract Method on the entire body of the new code, with Replace Additional Occurrences checked, and then inline the new method from the original call. That way you run less risk of choosing the wrong lines to extract.

Update: Here's an example:

You start with

extractableCode(1);
extractableCode(2);
extractableCode(3);

and extract the original block, leaving you with

extractedMethod(1);
extractableCode(2);
extractableCode(3);
...
function extractedMethod(int i) {
    extractableCode(i);
}

Your way would be to inline extractedMethod, then repeat the extraction with Replace All Occurrences. I'm suggesting instead that you extract from inside extractedMethod():

extractedMethod(1);
secondExtractedMethod(2);
secondExtractedMethod(3);
...
function extractedMethod(int i) {
    secondExtractedMethod(i);
}
function secondExtractedMethod(int i) {
    extractableCode(i);
}

Then inline your original call to the first extracted method:

secondExtractedMethod(1);
secondExtractedMethod(2);
secondExtractedMethod(3);
...
function secondExtractedMethod(int i) {
    extractableCode(i);
}

And then, probably rename the second extracted method. It's only a tiny bit different from what you originally suggest, but it might be a little more reliable.

Upvotes: 1

Related Questions