Mar 312007

From Wikipedia:

When applied to object-oriented programs, the Law of Demeter can be more precisely called the “Law of Demeter for Functions/Methods” (LoD-F). In this case, an object A can request a service (call a method) of an object instance B, but object A cannot “reach through” object B to access yet another object to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B’s internal structure. Instead, B’s class should be modified if necessary so that object A can simply make the request directly of object B, and then let object B propagate the request to any relevant subcomponents. If the law is followed, only object B knows its internal structure.

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

In particular, an object should avoid invoking methods of a member object returned by another method.

I’m not sure how valuable this advice is. If you follow it strictly, you’ll be spending a lot of time adding (and modifying) wrapper methods, which is probably just as bad, complexity-wise because what you gain in direct decoupling is lost by indirect coupling (not to mention interface pollution). Perhaps the better advise is to be conscious when you break the Law, i.e., when you write:

x.y().z();

…you should pause and think whether the class of ‘x’ would tolerate having a method of its own that accomplishes the same work, thus simplifying things for its users. Often, however, a type of object returned by the methods of a class serve too many multifarious purposes, making wrapping its methods quite heavy business and, in fact, more confusing than just leaving the class’s clients to deal with that type directly.

So a good rule is to ask ‘how broad is the scope of the returned type’s uses?’ If the functionality needed of the returned type is significantly narrower than that type’s public interface, consider wrapping it; otherwise, you’re just likely to do more harm than good.

Posted by Brian Will

Leave a Reply

(required)

(required)