Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Custom Refactoring in IntelliJ

This question is a follow-up for this.

Say I have some class Foo.

class Foo {
    protected String x = "x";

    public String getX() {
        return x;
    }
}

I have a program that uses Foo and violates LoD (Law of Demeter).

class Bar {
    protected Foo foo;

    public Bar() {
        this.foo = new Foo();
    }

    public Foo getFoo() {
        return foo;
    }
}

public static void main(String [] args) {
    Bar bar = new Bar();
    String x = bar.getFoo().getX(); 
}

I can refactor this code to use LoD in two steps.

  1. m bar.getFoo().getX() -> getFooX(bar) (extract to method, also find and replace occurrences)
  2. F6 getFooX(bar) -> bar.getFooX() (move to instance method, also find and replace occurences)

The program that uses Bar no longer violates LoD.

class Bar {
    protected Foo foo;

    public Bar() {
        this.foo = new Foo();
    }

    public Foo getFoo() {
        return foo;
    }

    public String getFooX() {
        return foo.getX();
    }
}

public static void main(String [] args) {
    Bar bar = new Bar();
    String x = bar.getFooX();
}

I am wondering if there is a way to make a custom refactoring method in IntelliJ that would consolidate these two steps into one.

EDIT I got a reply from JetBrains with a link to a pre-existing feature request. Please vote on it if you find this useful!

Hello Michael,

Seems we have similar request in YouTrack: https://youtrack.jetbrains.com/issue/IDEA-122400. Feel free to vote for it and leave comments.

Best regards, Yaroslav Bedrov JetBrains

EDIT There is at least a way to inspect for Law of Demeter issues. screenshot

Here is a gist that contains an inspection profile that will just look for LoD violations. You can import it into IntelliJ.

like image 463
michaelsnowden Avatar asked Jul 03 '15 20:07

michaelsnowden


People also ask

How do I refactor in IntelliJ?

Invoke refactoringSelect an item to refactor. You can select a file/folder in the Project tool window or expression/symbol in the editor. Press Ctrl+Alt+Shift+T to open a list of refactorings that can be selected. Alternatively, you can use a keyboard shortcut for a specific refactoring.

How can I beautify Java code in IntelliJ?

Go to Settings/Preferences | Editor | Code Style, select your programming language, and open the Wrapping and Braces tab. In the Keep when reformatting section, select the formatting rules which you want to ignore and deselect those which should be applied. Reformat your code ( Ctrl+Alt+L ).

How do I refactor imports in IntelliJ?

IntelliJ IDEA suggests to import single classes by default. You can change the settings to import entire packages instead. In the Settings/Preferences dialog ( Ctrl+Alt+S ), select Editor | Code Style | Java | Imports. Clear the Use single class import checkbox, and apply the changes.

What is an example of refactoring?

Examples are: adding, removing, and introducing new parameters, replacing the parameter with the explicit method and method call, parameterize method, making a separate query from modifier, preserve the whole object, remove setting method, etc.


Video Answer


1 Answers

After adding the getFooX() method to Bar, I would use Edit > Find > Replace Structurally with the following expressions:

Search template:

$instance$.getFoo().getX()

Replacement template:

$instance$.getFooX()

It does the job perfectly. Maybe you can add some constraints to $instance$ variable to narrow the search but that would only be useful if you had multiple classess with that method name.

like image 156
Daniel Cerecedo Avatar answered Sep 28 '22 13:09

Daniel Cerecedo