Law of Demeter

Travis Himes

github.com/thimes/DemeterDemo

Intro

  • Who Am I?
    • Developer for ~12 years
    • Android Developer at DramaFever
  • What do I plan to cover?
    • Law of Demeter What, How, Why?
  • Interrupt, Ask Questions, Give Feedback!

Law of Demeter

a.k.a. "Least Knowledge Principle"

Wikipedia Definition includes:

  • "Each unit should have only limited knowledge about other units: only units "closely" related to the current unit."
  • "Each unit should only talk to its friends; don't talk to strangers."
  • "Only talk to your immediate friends."

Show me the pain!

... or "what does this look like in practice?"

Consider this snippet of code:

...
if (car.getDrivetrain().getEngine().getGasType() == GasType.DIESEL) {
   // TODO: do some cool stuff...
}
...

What stands out?

Rating: BAD

Consider this snippet of code:

...
if (car != null 
       && car.getDrivetrain() != null 
       && car.getDrivetrain().getEngine() != null 
       && car.getDrivetrain().getEngine().getGasType() == DIESEL) {
   // TODO: do some cool stuff...
}
...

Now what do you see?

Rating: LESS BAD

Consider this snippet of code:

...
if (car.getTypeOfGasUsed() == GasType.DIESEL) {
   // TODO: do some cool stuff...
}
...

That's a lot nicer!

Rating: GOOD

Look at this:

...
if (car.usesGasType(GasType.DIESEL)) {
   // TODO: do some cool stuff...
}
...

Do you see the difference?

Rating: BEST

Sounds Great

How do I get started?

Don't do this...

class Car {
   ...
   boolean willRunOn(GasType gasType) {
      return drivetrain != null 
                && drivetrain.getEngine() != null 
                && drivetrain.getEngine().getGasType() == gasType;
   }
   ...
}

Why not?

Do this...

class Car {
   ...
   boolean willRunOn(GasType gasType) {
      return drivetrain != null && drivetrain.willRunOn(gasType);
   }
   ...
}
class Drivetrain {
   ...
   boolean willRunOn(GasType gasType) {
      return engine != null && engine.willRunOn(gasType); 
   }
   ...
}
class Engine {
   ...
   boolean willRunOn(GasType gasType) {
      return correctGasType == gasType;
   }
   ...
}

same name: coincidence, NOT an interface

Why?

  • Place the responsibility on your objects
  • Protect yourself from change
  • Save on typing!

Downsides?

  • Can have overly specific methods
  • Lots of code up front to save pain on changes in the future

Do This

Not This

boolean willRunOn(GasType gasType);
boolean willRunOnDiesel();
boolean willRunOnPetrol();
boolean willRunOnJetFuel();
boolean willRunOnRedBull();
boolean willRunOnPropane();
...

You said something about interfaces in the meetup description...

Same deal, it applies there too

Thanks!

  • Why present this?
  • Questions?
  • Katas

clone github.com/thimes/DemeterDemo

Demeter

By Travis Himes

Demeter

Slides for the Law of Demeter talk

  • 1,092