Vince
Vince

Reputation: 15156

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

Upvotes: 4

Views: 1152

Answers (2)

Grim
Grim

Reputation: 2026

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.

Upvotes: 5

Sarthak Mittal
Sarthak Mittal

Reputation: 6104

Since Law of Delimiter is a specific case of Loose Coupling.

The way i think it works is:

We can access fields of a particular class and its methods even though we are chaining multiple methods(say). We do it all the time in java, the thing to note is that, chaining is only applied for methods of a single class.

Delimiter's law cautions us from accessing objects and/or methods of multiple classes at once.

Example:

if we have classes A, B, C.

B class has a field holding a reference of A, and C has reference of B.

Then we should not fetch reference of A through C by using getters, it helps in maintaining Loose Coupling.

Again, this is the way i think it works.

Upvotes: 0

Related Questions