Monday, 14 March 2011

Law of Demeter

The Law of Demeter keeps popping up in various software blogs and writings and I have to hold my hand up and say that I’ve never really understood what it meant. So, this blog corrects all that.

A quick bit of googling tells me that:

“The classic ‘Law of Demeter’ refers to a paper that was published in IEEE Software in 1989.
Lieberherr, Karl. J. and Holland, I.
Assuring good style for object-oriented programs
IEEE Software, September 1989, pp 38-48"

Reading in to this, there are four Laws of Demeter, which state that for any given method of an object, then that method will invoke the methods on the following objects:
  1. It can invoke methods on itself.
  2. It can invoke methods on its parameter arguments.
  3. It can invoke methods on any object it instantiates.
  4. It can invoke methods on it instance/class variables.
… but what does it actually mean? As ever, I think that the best way of demonstrating it is with Java code.

/**
* This example demonstrates the four laws of Demeter - which basically boils down to:
* "Only talk to your immediate friends"
*
*/
public class LawOfDemeter {

 
private Thingy instanceVar;

 
/**
   * This method demonstrates adherence to the four rules.
   *
   *
@param arg0
   *            Any old argument
   */
 
public void adheringToTheLaw(Thingy arg0) {

   
// 1) It's okay to call our own methods
   
doSomeThing();

   
// 2) It's okay to call methods on objects passed to us.
   
arg0.method1();

   
// 3) It's okay to call methods on objects created by this object.
   
Thingy var = new Thingy();
    var.method1
();

   
// 4) Your method can call methods on its instance variables.
   
instanceVar.method1();
 
}

 
/**
   * This demonstrates one way of breaking the law of demeter.
   *
   *
@param arg0
   *            An argument
   */
 
public void breakingTheRules(Thingy arg0) {

   
// The method requires a method of type AnotherObject and not Thingy
    // so the repaired method signature should read
    // public void notBreakingTheRules(AnotherObject arg0);
   
arg0.getAnotherObject().method2();
 
}

 
private void doSomeThing() {
   
// Do something
 
}
}

No comments: