Search code examples
javac#ooplaw-of-demeter

What is Law of Demeter?


Let's start with Wikipedia:

More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:

  1. O itself
  2. m's parameters
  3. Any objects created/instantiated within m
  4. O's direct component objects
  5. A global variable, accessible by O, in the scope of m

Rule 1:

public class ClassOne {

    public void method1() {
        method2();
    }

    public void method2() {

    }
}

Rule 2:

public class ClassOne {

    public void method1(ClassTwo classTwo) {
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}

Rule 3:

public class ClassOne {

    public void method1() {
        ClassTwo classTwo = new ClassTwo();
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}

Rule 4 (thanks @juharr):

public class ClassOne {

    private ClassTwo classTwo;

    public void method1() {
        classTwo = new ClassTwo();
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}

Rule 5:

?

Can anyone help me with Rule 5?


And doesn't Law of Demeter imply that chaining is bad?

User.getName().getLastName();

This leads to high coupling.


Isn't "Tell, don't ask" a similar principle?

So is this everything? Am I wrong about something? How can you obey Law of Demeter?


Solution

  • "Tell don't ask" is a bit different.

    Demeter: don't get something to get something from that to do something on the final thing.

    TDA: don't retrieve "information" from another object to then make a decision on that. Simple example:

    if (someList.size() == 0) { bla
    

    vs.

    if (someList.isEmpty()) { bla
    

    In both cases you are calling a method on some other object; but there is a key difference: the first call exposes "internal" state of that other object to you; on which you then make some decision. Whereas, in the "TDA" improved second version; you leave that "status evaluation" within that other object; thereby somehow reducing coupling.

    But just for the record: that second example still makes a decision based on the state of that list. From that point of view, it is just a slightly better version than option 1. Ideally, you wouldn't need such checks.