Object-oriented Programming (OOP) Notes

Russell Bateman
last update:


Common mistakes in class design

The law of Demeter

This is a discussion of theory.

This law of object-oriented implementation states that, (this is recouched using Java terminology)

for all classes C, and for all methods M, all objects to which M sends a message (i.e.: consumes) must be:

  1. this,
  2. M's arguments,
  3. instance variables of C,
  4. objects create by M, or by methods that M calls, or
  5. objects in static fields.

An illustration of #1:

public class NetworkConnection
{
  public void close()
  {
    sendShutdownMessage();
  }

  private void sendShutdownMessage()
  {
    ...
  }
}

An illustration of #3:

public class NetworkConnection
{
  private Socket socket;

  public void close()
  {
    socket.close();
  }
}

Working backwards, what does this law prohibit?

First off, this tends to preclude writing classes that contain static, utility methods because the object acted upon are often created elsewhere. A good example is StringUtilities because it typically contains methods that act upon Strings that don't meet any of the five criteria above.

Consider this method in class NetwareConnection:

public class NetworkConnection
{
  public void send( Person person )
  {
    sendBytes( person.getName().getbytes() );
    ...
  }
}

It is not an illustration of #2 above despite that person is an argument, it's not an object of type C. It is permissible to call call methods of type Person on person, for example, to induce person to behave in some way, but it's not permissible to call an accessor like getName() since it produces an object that doesn't belong to NetworkConnection in the way listed among the five rules.

So-called fluent APIs are granted under rule #4:

Report report = new ReportBuilder()
              .withBorder( 1 )
              .withBorderColor( Color.black )
              .withMargin( 3 )
              .withTitle( "Law of Demeter Report" )
              .build();

Most, if not all of the negative examples, that is, of violating the law of Demeter, involve getter methods. In conclusion, examples of its violation are really examples of what everyone does all the time.