Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 951
Anonymous Avatar asked Mar 10 '16 19:03

Anonymous


People also ask

Why is it called Law of Demeter?

It is so named for its origin in the Demeter Project, an adaptive programming and aspect-oriented programming effort. The project was named in honor of Demeter, “distribution-mother” and the Greek goddess of agriculture, to signify a bottom-up philosophy of programming which is also embodied in the law itself.

What is the Law of Demeter in Java?

According to the law of Demeter, classes should know about and interact with a few other classes as possible. It is used to loosen the coupling by limiting class interaction with other classes to provide stability as tighter coupling makes the program difficult to maintain.

What is the Law of Demeter trying to prevent?

The Law of Demeter asks us to minimize coupling between classes and avoid reaching out to the third object in order in order to make refactoring and developing new features easily.

What is one way of describing the Law of Demeter?

The Law of Demeter is often stated as, “only talk to your immediate friends.” In Object Oriented languages that use a dot as the field identifier this is often simplified to, “only use one dot.” While this is an interesting heuristic of sorts, it's a very poor rule to follow because it's almost never that simple.


2 Answers

"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.

like image 198
GhostCat Avatar answered Oct 07 '22 14:10

GhostCat


The 5th is difficult to represent in C# or Java, since they don't technically support global variables. However, in a design pattern that is similar in principle, you could have e.g. a configuration class that just contains globally-accessible static configuration values, such as (C#):

internal class MyConfiguration
{
    private static String MyConfigurationValue; // set in constructor
    MyConfiguration(){ MyConfigurationValue = DoSomethingToLoadValue(); }
    public static String GetMyConfigurationValue(){ return MyConfigurationValue; }
}

In this case (assuming the design pattern was acceptable in all other ways), the Law of Demeter would allow this, since it is globally accessible and intended to be that way.

like image 43
Matt Jordan Avatar answered Oct 07 '22 14:10

Matt Jordan