Law of Demeter

From CSSEMediaWiki
Revision as of 03:35, 14 August 2008 by Geoffrey Clark (Talk | contribs)
Jump to: navigation, search

The Law of Demeter says that an object cannot request services from an object via a different object.

"More formally, the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:

  1. O itself
  2. M's parameters
  3. any objects created/instantiated within M
  4. O's direct component objects" --[Wikipedia]

A common (but certainly not the only) indicator of a violation of the law in some languages is more than one dot in a line of code, for example man.getTrousers().checkPocketContents().

Contents

Consequences

A violation of the Law of Demeter means that the caller object is dependant on the internal structure of the object it accesses. In the above example, if the Trousers class were to change (to say, Shorts, or perhaps a more abstract piece of clothing) the original caller would need to be updated.

Solution

The best solution is to write wrapper methods in the class to allow callers to ask that class for information about objects it contains. Unfortunately this may mean the class presents a very large public interface.

Example

Consider a simple graphics example. A 3D scene contains a number of point clouds (amongst other things which we'll ignore). Each PointCloud consists of a number of vertices. Here is the class diagram initially:

Demeter.png

In this design, if a Scene requires a PointCloud to be displayed it will need to get the list of vertices from the PointCloud first. Then it can display each vertex in turn. In this case, it should seem fairly obvious that something is wrong. In fact, the Law of Demeter has been violated, since the Scene obtains vertices through the PointCloud and calls their method. If the PointCloud were to change how it is composed, then Scene will most likely need to be modified (unless getVertices is modified to create a list from the new representation, but this could be messy). The solution in this case is fairly simple. PointCloud requires a display() method which displays each of its vertices. Scene can then simply call this method. The (slightly) modified version is shown below:

Demeter2.png

Example 2

I spoke to Wal just after the lecture and we were talking about the Law of Demeter, and a situation arose which I have documented below in the UML diagram.

Carengine1.jpg

It is possible that in this design you could say...

  car.getEngine().start()

But the Law of Demeter states that generally more than one dot in a line of code is a sign that the law has been broken.


We also talked about another way this design could be approached in order to satisfy the Law of Demeter. The below design would satisfy the law because the start() method in the Car class could look a little something like this...

start()
{
    engine.start();
}

Carengine2.jpg

Personal tools