Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Un-encapsulate refactoring in Eclipse or Intellij?

Consider a wrapper class W, wrapping C, this meaning that for most attributes of C, there is a correspondent attribute A on W, its logic consisting in nothing more than delegation to C's A. This situation can be most precisely depicted with the sketch shown below:

class W {
    private C c;

    getX() { return c.getX(); }
    getY() { return c.getY(); }
}

The trouble is that I've decided that I wan't to get rid of getX(), and I'd prefer to either as a transitory step to put C c as public, having all the calling code of W do a w.c.getX() or w.c.getY() or alternatively to put create a W.getC(), and have all calls to getX() and getY() go through it.

What this all boils down is to an "un-encapsulate" refactoring. Is there anything performing this much needed task either in Eclipse or Intellij?

like image 979
devoured elysium Avatar asked Jan 15 '23 18:01

devoured elysium


1 Answers

With IntelliJ you can use the Remove Middleman refactoring.

Consider:

Before:

public class W {
    private C c;

    Object getX() { return c.getX(); }
    Object getY() { return c.getY(); }
}

public class C {
    private Object x;
    private Object y;

    public Object getX() {
        return x;
    }

    public Object getY() {
        return y;
    }
}

public class UsesW {
    W w;
    public void useW() {
        Object x = w.getX();
        Object y = w.getY();
    }
}

Place your cursor on the declaration of W.c. Then choose Refactor | Remove Middleman. The result gets you halfway to where you want to be:

After:

public class W {
    private C c;

    public C getC() {
        return c;
    }
}

/* class C is unchanged */

public class UsesW {
    W w;
    public void useW() {
        Object x = w.getC().getX();
        Object y = w.getC().getY();
    }
}

Then you can introduce a variable of type C in UsesW. Place your cursor over one of the calls to w.getC() and inline it: Refactor | Inline... (Ctrl-Alt-N is the default shortcut), choosing to inline all instances. It'll leave you with this:

public class UsesW {
    W w;
    public void useW() {
        final C c = w.getC();
        Object x = c.getX();
        Object y = c.getY();
    }
}

Finally getting rid of W altogether is something you probably can answer better than me, but now that job became significantly easier.

like image 132
Daniel Miladinov Avatar answered Jan 23 '23 15:01

Daniel Miladinov