ооп – Clean Code: The Obscure Law of Demeter

Question:

Now I'm reading the book Clean Code on a small chapter about the law of Demeter. Before that, I encountered him in patterns from O'reilly (HeadFirst) and there was a little and understandable. After a clean code – a mess in my head. There are a couple of questions:

1) Martin divides objects into objects and data structures. What is meant by structure here? Struct (in c# for example) or in general a class object in which, apart from public fields (or properties), there is nothing else (methods, for example)?

2) From the first question, there is a misunderstanding of what is meant by a hybrid (half object, half data structure), which is better not to write. Is it considered a hybrid, for example, an object of the "Car" class, where you can see its color, and even change the wheels, and does it also have behavior?

3) This question was raised for oral discussion in other developers (we are not junes, but not "cool guys") and there was also a misunderstanding of the very essence of this law, why it should be observed, which is the main reason: either the basis for further easy changes, or concealment the internal structure of the object, or even easy prevention and handling of NullReferenceException? Everyone understands differently.

4) Is the law violated when dividing "bad" methods into many small ones?

It was

public class Class1
{
    public String DoSmth()
    {
        //Вроде как закон нарушен, потому что вызываем метод у вернувшегося значения
        return MethodClass1().DoSmth();
    }

    public Class2 MethodClass1()
    {
        return new Class2();
    }
}

public class Class2
{
    public String DoSmth()
    {
        String res2 = this.MethodClass2();
        return res2;
    }

    public String MethodClass2()
    {
        return "test";
    }
}

It became

public class Class1
{
    public String DoSmth()
    {
        //теперь тут вызываются только методы того же класса
        Class2 res1 = MethodClass1();
        return this.MethodClass1_2(res1);
    }

    public Class2 MethodClass1()
    {
        return new Class2();
    }

    public String MethodClass1_2(Class2 val)
    {
        return val.DoSmth();
    }
}

Another small update: I personally have the following attitude so far: this is some kind of rule, the need for explicit violation of which is an indicator that something is not designed that way and you can find a solution that will be better both in terms of business logic and in the future escort.

Answer:

In The Pragmatic Programmer (Hunt, Thomas) Demeter's law (such a crooked translation) is reduced to a short statement:

Minimize coupling between modules

Example from a book in C++

class Demeter
{
    private:
        A* a;
        int func();
    public:
        void example(B& b);
}

void Demeter::example(B& b)
{
    int f = func(); // 1

    b.invert();     // 2

    a = new A();
    a->setActive(); // 3

    C c;
    c.print();      // 4
}

The law of Demeter for functions states that any method of some object can only access methods belonging to:

  1. to ourselves
  2. any parameters passed to the method
  3. any objects it creates
  4. any directly contained component objects

Based on this, we can answer your question #3: decoupling makes it easier to modify and maintain the code, and it makes it easier to write tests.

In practice, this means that you will have to create a large number of wrapper methods that simply route the request further to the delegate. These wrapper methods incur costs by degrading performance and taking up memory.

By reversing the law of Demeter and tightly linking several modules, performance gains can be obtained.

Scroll to Top