17

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.

3
  • I'm wondering if it's possible to accomplish in one step with current IDEA version (v14), I didn't find any appropriate single command. It might be a good idea to submit a feature request if this function is really missing. Commented Jul 10, 2015 at 0:06
  • 1
    @erkfel I's currently being reviewed. The link doesn't look active yet, but it should be here: intellij-support.jetbrains.com/hc/en-us/requests/66429 Commented Jul 10, 2015 at 6:07
  • 1
    @erkfel See my edit, and checkout youtrack.jetbrains.com/issue/IDEA-122400 Commented Jul 10, 2015 at 20:33

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.