Search code examples
javagetterlaw-of-demeter

Do getters violate the Law of Demeter?


Imagine there was a GameState type which uses a GameContext (via a process method):

abstract class GameState {
    public abstract void process(GameContext context);
}

GameContext would contain things such as the Player, Shops, ect.. things that are essential to the game.

A state would access what it needed:

class CombatState extends GameState {
    public void process(GameContext context) {
        Player player = context.getPlayer();

        if(player.isAlive()) {
            //...
        }
    }
}

The statement player.isAlive() could be rewritten as context.getPlayer().isAlive().

My Question

The Law of Demeter states that objects should only interact with direct relatives. Would this be a violation of the principle, and how would it be resolved?

For each state to be handled dynamically, the formal parameters must be acceptable by all possible states. This makes it hard to pass the object strictly what it needs, which is why each state grabs what it needs from a "main source". I feel that main source has very low cohesion, since a ShopState would require different data than a CombatState


Solution

  • A State is not a Process, a Process is a Process. To fight is a process, to be alive is a state.

    Using the abstract name of process makes you need to break the Demeter's law.

    Look this example:

    class CombatProcess extends GameProcess {
        public void hit(Player puncher, Player beaten) {
            if (beaten.getState().isAlive()) {
               Weapon oneWeapon = one.getCurrentWeapon();
                   ...
            }
        }
    }
    

    Everything in CombatProcess is as concrete as it could.

    To analyze what player fights against what player is NOT the responsibility of the CombatProcess itself! Before the CombatProcess starts you must know who you fight against.

    EDIT:

    In the comments of this answer you wrote:

    If I had the states in a Set, List or Map, I would not be able to polymorphically process the states,

    This is absolutly correct. The Hook/Anchor-Pattern is from 1996 and still used widely and glory in windows (so called system-hooks). Unfortunately It did not find his way to the top 10 patterns of OOD because of a few critics. One of this critic is :

    ... its not easy to abstract all the operations of a process into logical independent hooks, and to thereafter anchor them and iterate them properly.

    My private opinion is that the Hook/Ancher-Pattern was revolutionary in 1996 and will be revolutionary in the combination with the CDI (spring in example) in the future.

    Finally! You could decide:

    1. Break the Law of Demeter.
    2. Drop the Hook/Ancher-Pattern.
    3. Write a workaround described here.