
Law of Demeter and immutability - speckz
http://enterprisecraftsmanship.com/2016/09/29/law-of-demeter-and-immutability/
======
whack
The author claims that Dementer's law is primarily there in order to prevent
state corruption. I don't know if I agree with this premise. There are also 2
other reasons to follow Dementer's law:

1\. Make it easier for your users to achieve specific goals through a single
method call, instead of having to know & go through a chain of method calls.
Ie, instead of having to know that the Dog object has Leg sub-objects, and
having to call Dog.getLeg().selectMuscle().contract(), the user can instead
just invoke Dog.move(). This enhances simplicity, and makes life easy for your
users.

2\. Hiding implementation details from your users, in order to maintain
flexibility for future changes. If all your users are calling
Dog.getLeg().selectMuscle().contract(), then you're forced to work with this
Dog->Leg->Muscle implementation. On the other hand, if your users are simply
calling Dog.move(), then you're free to refactor the class internal structure
in dramatic ways.

The fact that an object is immutable, has little impact on the 2 benefits
given above. Dementer's Law/Guideline would be well worth paying attention to
for those reasons, even when dealing with ImmutableObjects.

~~~
vkhorikov
Coupling is an important concept but I think this concern can be mitigated by
following the DRY principle. That is, if you have only one function that knows
about the object’s internal structure (“couples” to it, so to speak), it
doesn’t really matter where exactly that function is located – in the class
itself or in some other place.

Also, your example isn't entirely valid as you mutate the objects' state.

~~~
jessedhillon
Demeter's Law is also called the Principle of Least Knowledge. The reason
being that, if you have two dogs -- one robotic and one mammalian -- reading
the angle of the second joint distal from the hip is going to walk a distinct
path for each type, which requires some otherwise-dog-agnostic piece of code
to now know about what types of dogs exist and how to traverse their skeletal
chains.

IMO Law of Demeter is not chiefly about state protection -- it's a principle
of good design which, when followed, unburdens developers from the cognitive
load of keeping the entire universe in their heads. It forces them to think
about what is the smallest amount of information this component needs in order
to function.

~~~
vkhorikov
I do agree with this one.

------
Conlectus
There is in my mind another important benefit of following the Law of Demeter:
it minimizes coupling.

Even in functional programming if you are digging into a data structure 5
levels deep, you are potentially coupling a function to 5 different
structures, rather than just one.

For example: game.player.bbox.topLeft.x has the potential to break if the
game, player, bbox, or point structure change, which makes it fragile. If
using an IP language with inheritance, it could also break if any of their
super classes change.

~~~
TickleSteve
Coupling is what the LoD is about, not mutability, its not just another
important benefit, its the main point.

------
regularfry
Disagree with the premise. The purpose of Demeter isn't to prevent one class
from mucking up the internal state of another, that's a side-effect. Its
purpose is to prevent one class from being coupled to the internal structure
of another so that if you change one, you don't have to change the other. It
stops _code_ updates, not _state_ updates, from rippling out.

This is why the _original_ formulation of the LoD didn't talk about instances,
it talked about _classes_. You were only allowed to know about the surface-
level structure of your neighbours, but anything else of the same class as
your neighbours was fair game. So in the `player.Position.X` example, we
actually don't have enough information to know if it's a violation or not: we
don't know what class `player.Position` is, and we don't know whether it's a
legitimate neighbour class. If there's another `Position` field somewhere in
scope that's legit, `player.Position.X` is allowed, because we're already
coupled to that structure, and getting to it via the `player` object doesn't
add any coupling that wasn't there already.

~~~
catnaroek
Getting most object-oriented programmers to think about the static structure
of their programs (e.g., classes rather than objects, variables rather than
runtime values) is going to be an uphill battle.

------
debacle
> The law of Demeter is a guideline

I'm not really sure that much more had to be said than that. There are many
instances (especially when you have a data structure that is also a class)
where the law of Demeter is a guideline and just that.

However, the caveat is that this:

    
    
        int positionX = player.Position.X;
    

Should really look like this:

    
    
        if(player.Position != null) {
          int positionX = player.Position.X;
        }
    

In which case having a getter eliminates the need for error handling to be
spittled all over the codebase. Having an accessor means you can nip checking
for a null reference in the bud. There are other benefits as well.

~~~
lomnakkus
... or you could just use a language which doesn't allow "null".

~~~
debacle
I can't think of a programming language used for game development that doesn't
have null.

~~~
kazagistar
In Rust, an `&Thing` (reference to thing), `Option<&Thing>` (optional
reference to thing), `Box<Thing>` (thing on the heap), and
`Option<Box<Thing>>` (optional thing on the heap) all have the same in-memory
representation of a single pointer, but prohibit accidentally dereferencing a
null pointer, and make non-nullable pointers the default.

~~~
coldtea
That made my head hurt.

------
xsmasher
End goal is to make code that is easier to maintain and understand.

The intermediate goals should be to reduce coupling, increase encapsulation,
etc. These are tools to achieve the end goal.

Multiple dots is just a code smell, indicating that you're probably not
meeting your intermediate goals or the end goal. If you see multiple dots, you
should probably examine that code to see if it "wants" to be somewhere else,
in service of the Primary goal.

But if you elevate "multiple dots" to the level of a "Law" then you're looking
at the problem from the wrong end, and are in real danger of losing sight of
the end goal. You can follow this law right down a hole that works AGAINST
your real goal.

------
Koshkin
This "law" sounds like a reasonable idea, at first, but if you think about it
for a few seconds, you'll realize that it makes little, if any, sense (at
least, when taken out of some specific context). As the designer of the class,
often neither you can possibly anticipate all the ways in which objects of the
classes involved will be used, nor would you _want_ to re-expose all (or some
of) the APIs provided by the "subordinate" classes.

~~~
coldtea
> _As the designer of the class, often neither you can possibly anticipate all
> the ways in which objects of the classes involved will be used_

That's why you subclass -- or compose. The subclass can use them in other
ways.

The problem with what you say, that you can't "possibly anticipate all the
ways in which objects of the classes involved will be used" is that if you let
that happen, then you have to forever support the different ways by which they
are used -- and you can't change your implementation internally, make it more
efficient etc, because different external code uses various internal details
of it.

------
Rickasaurus
Gross mutable OO null-defensive nonsense.

