Law Of Demeter

The LawOfDemeter specifies a style guideline: "Only talk to your immediate friends." E.g. one never calls a method on an object you got from another call nor on a global object. This helps a lot later when you ReFactor the code.

http://www.ccs.neu.edu/research/demeter/papers/law-of-demeter/oopsla88-law-of-demeter.pdf

PeterVanRooijen posted the following description of the LawOfDemeter to Usenet:


Explanation in plain English:

but


One should not have a chain of messages a.getB().getC().doSomething() in some class other than a's class.

I have a slight problem with this. Even if you limit calls to a.getB().getC().doSomething() to within class 'a', aren't you still violating the principle in terms of 'b' since 'a' is calling b.getC().doSomething() ?

So 'b' needs a method called doSomething() that calls c.doSomething() and then 'a' needs a method called doSomething that calls b.doSomething()


Here's an exact quote briefly summarizing the topic from a slide for a university course found on the web, maybe it'll help clarify the historical confusion on this page:

Law of Demeter

Note: format changed by a WikiGnome. Original at http://isys.uni-klu.ac.at/ISYS/Courses/02WS/sete/folien/Fse0207_DFDConcepts.pdf (Google HTML version, strip everything before www.isys for address of original PDF).

An alternative take (trying to improve) is proposed in LawOfDemeterRevisited.


Before reading further please see LawOfDemeterVsInformationHiding, LawOfDemeterMakesUnitTestsEasier, LawOfDemeterIsHardToUnderstand, LawOfDemeterIsTooRestrictive, LawOfDemeterAndCoupling.


The Demeter literature talks about the introduction of lots of additional small methods, which started getting unwieldy to add manually, and is part of why the Demeter tools exists, so they can be autogenerated as needed.

This gets into issues of propagation of results of partial computations, which is a whole other area of Demeter called "propagation patterns" (not be confused with "design patterns"). Beyond the straightforward stuff, trying to go "full" Demeter without the niceties of the "full" Demeter system has lots of not niceties" associated with it because without Demeter's tool-support you can't so easily propagate what is needed where in an orthogonal fashion. -- AnonymousDonor

I don't see this as a problem. I think FewShortMethodsPerClass and lack of FearOfAddingClasses fits LawOfDemeter. -- GuillermoSchwarz


LoD can be regarded as the principle of assuming "least structural knowledge" (something its creator calls "Structure-shy programming"). The idea is to assume knowledge of no object's internal structure other than your own immediate self.

When an object is encapsulating structural knowledge and you try to take advantage of that, your object method is making a rigid assumption about the traversal path to access that knowledgehen they represent facets of the problem domain.''

If a fundamental structural relationship in the domain really does change then its almost certain that a clients requirements of the interface will also change and thus the facade provided by the outer objects hasn't bought you anything other than an extra layer (or even several layers) of code to maintain. Conversely, a structural change that is not domain oriented should be hidden behind a bridge where it cannot affect the exposed structure.

Structural relationships between objects are a powerful abstraction mechanism in their own right, and thus a powerful force for simplicity when used in the right place -- Paul Campbell

The Law of Demeter is (or might be in some designs) related to the VisitorPattern: if you have to do something to object X at the end of a long chain of composites and accessors, the wrong way is digging up X yourself and perform the operation directly; one of the good ways is having a Visitor look for object X with the collaboration of all involved objects.

It is much less brittle because you don't need to know the details of the data structure; the visitor only needs to visit X to do its job. The visitor can also seek objects satisfying some condition.

The use of a visitor in this case is motivated by the fact that the intermediate objects don't know (and probably have no business knowing) how to do the special operation you want, but they can be expected to support a generic visitor.

Some work by KarlLieberherr (see his university page) has the purpose of generating the visitor infrastructure from object graphs; it can perhaps be considered an instance of AspectOrientedProgramming (the aspect of visiting messy object graphs). -- LorenzoGatti

Perhaps what is needed is a hierarchical composite - Pass the Person node to a FindWhateverVisitor class whose result is the value you need. Then person deductionProfiles last stateTaxDeduction amount each class may need a method that reports what elements are composites and leafs and a method to indicate what kind of composite it is, but you've removed the need for at least a part of this problem. The ImA() (or KindOf() ), MyLeavesAre() and MyCompositesAre() methods work well in testing as well if you've forgotten what is in your composite. Of course, this is more code that you may not need. -- WyattMatthews.

ObjectQueries? and the AdapterPattern are two ways to implement the LawOfDemeter. -- DaveOrme


You'll likely find similar code all over the system - That repetition is itself sufficient reason to refactor. OnceAndOnlyOnce. We don't need Demeter to tell us that. -- DaveHarris

My XP formulation about ShieldPattern is described in BridgePatternIsJustGoodFactoring. When we see a method like:

  person profiles identityProfile lastName
we tend to replace it with
  person lastName
with the appropriate definition of lastName in Person. Apply recursively. If you look at this from the viewpoint of ShieldPattern, you can say we do it because the handling of profiles is up to Person. We just think it makes the code look nicer ;-> (I oversimplify for effect, of course.) -- RonJeffries

I also create:

  person identityProfile
as
^self profiles identityProfile
Of course you see that kind of code all the time in Smalltalk, but very few times in Java.

-- GuillermoSchwarz


Sometimes different just think it makes the code look nicer ;-> (I oversimplify for effect, of course.) -- RonJeffries

I also create:

  person identityProfile
as
^self profiles identityProfile
Of course you see that kind of code all the time in Smalltalk, but very few times in Java.

-- GuillermoSchwarz


Sometimes different clients need different types of access. With regard to the dog mentioned above: A vet may very well want to violate a dog's encapsulation and manipulate its legs directly. So it seems like the LawOfDemeter, as an axiom, is flat out opposed to any sort of inspection/reflection business.

Reflection doesn't necessarily violate the LawOfDemeter if you keep in mind the "principle of least structural knowledge" definition. You're supposed to encapsulate structural knowledge in a few places in the code; nothing in reflection would necessarily contradict that. Now, if you make assumptions about what to look for when inspecting, that would need to be modified if the access path/interface changes, then that very well could be a violation of the LawOfDemeter.

See also: InterfaceMarket

A vet should be able to manipulate the Dog's leg as it is a 'visible interface'. He, however, can manipulate the Dog's intestinal parasites only via an available interface, i.e. the mouth, by the introduction of worming tables. To do otherwise, i.e. to operate, would break the 'rules'. -- NickAdie

In fact we can make the Leg interface visible only to the Vet. E.g. Dog exposes Leg objects via its allow_manipulation_by(Vet) method which only accepts a Vet. This method, if the Dog is not using the Leg, passes the Leg to the Vet by calling the allowed_to_manipulate(Leg) method, hence the interfaces must hold good if the interface check holds good. For real safety the Dog could pass a proxy instead which it can release at any point, that way the Vet cannot manipulate the Leg if the Dog does not like it. It occurred to me that following the laws of Demeter effectively prohibits return statements from methods. I find that banishing return statements from my code and solving problems without them has excellent effects on readability and flexibility of classes. In effect it forces two-way contracts between objects, which seems to be beneficial. Unlike the following post, I have found this extends to Collections and ValueObjects?. Factories, however, do seem to need to return objects. -- MikeAmy?


I've had success applying the Law of Demeter by allowing exceptions for three kinds of class:

So, in my code the Law of Demeter only applies to ReferenceObjects that embody domain knowledge. This has been very successful in making code easy to read, easy to test and easy to change. The use of automatic refactoring tools helps a great deal with the "easy to change" aspect, so I'm not sure how well this would work in a more manual coding environment. -- NatPryce


See DemeterGoddess to see where this name came from.

I wonder CanLawOfDemeterBeRefactoredAutomatically?

See also: EncapsulationIsHierarchical, TreeOrientedPerspective, TellDontAsk, ShieldPattern, CapabilityComputing, LawOfDemeterExample, AlternateHardAndSoftLayers, ShearingLayers.

Other references:


We think it's possible to try too hard to avoid violating this rule. For example, adding in 'convenience' methods, which act as bridges, or over-zealous use of the ShieldPattern.

We've just finished a pair-programming session where we've found that taking out these convenience methods helps to reveal FeatureEnvy, which in turn indicates refactorings which otherwise would have remained hidden.

And finally, there's no problem breaking LawOfDemeter in tests, right? -- MalcolmSparks, EamonWalshe (pairing)


IOW: do not call

foo.getBar().doSomething()

instead, implement doSomething() on Foo by having it call bar. I would like a JavaLanguage feature allowing you to do this declaratively.

  class Foo implements IBar {
// all calls to IBar methods on Foo get implemented by calls to this variable  
IBar myIbar implements IBar;

// except for barMethod, which I implement here explicitly void barMethod3() {...} }

the compiler would generate methods barMethod1(), barMethod2(), barMethod4() etc.

Or you could just use Objective-C or Smalltalk...

Is this generally refuting the technique of "pathing", such as that commonly found in JavaScript DOM references where you get long references? They tend to look like:

  todds.parents.dogs.bitee.brothers.house.garage.door.open();

Well, in that case the structure may actually be important. But often it's still better to get a hold of objects via id references...


Trying to come up with a more simple (non-foobar) example, is this correct?

currentPerson.Account.Deposit(500)<-- bad
Account.Deposit(currentPerson, 500)<-- good
Reason:
Account may need to be initialized before it can be accessed
Say currentPerson.Account = null, will throw null reference exception in bad code
In good code, Deposit method can check if null and setup a new one before depositing


currentPerson.give(500)<-- best
Reason:
LawOfDemeter implies you shouldn't care how currentPerson stores his money, just that he gets it.
You do not care if he puts it in a bankAccount, usedSock, hiddenSafe, or 
happens to be a 'CEO extends person' who calls myInvestmentManager.handleMoneyForMe(500)

-- AnonymousStudent? (reading this page taught me all I needed to know to understand this, you guys are educational!)


In a banking system you would give money to someone's account not to them, so far from being bad, navigating via the account object would convey essential semantics for example in the case the person had multiple accounts. If you have a canonical domain model then the all object relationships convey essential semantics about the information that is being represented. If you bridge those relationships before presenting access to client code then that information is lost. The fact that you could afford to bridge it implies that the structural information wasn't needed and hence your model wasn't canonical. If your model is non-canonical then refactor it so it is - don't bridge it. Of course your client code will then be dependent on the structure of your model but that is essential in order for the it add value to the system. Hence so long as your model is canonical with respect to the problem domain then LawOfDemeter is an anachronism.

-- Paul Campbell


What about when you want to look something up in a dictionary with more than one index in something like Java? You could define a pair object with a comparable interface on it, but that requires writing a new class for each different number of indices. I think a more natural way of doing this is curried dictionaries, like HashMap<FirstIndex?, HashMap<SecondIndex?, Value>>. Then when looking up you do dictionary.get(firstIndex).get(secondIndex).

Seems to me that repeatedly typing dictionary.get(firstIndex).get(secondIndex) each time you access something is at least annoying and error-prone, and maybe even a CodeSmell to use OnceAndOnlyOnce (am I correct?).
My guess at a better way would be something like:

class myComplexDict { private myMap = new hashMap<firstIndexType, HashMap<secondIndexType, Value>>; public Value get(firstIndex, secondIndex) { return this.myMap.get(firstIndex).get(secondIndex); } }

This also gives you more freedom to change implementation if Java suddenly decides to implement a 'multiDimensionMap<K[], V>' in some future specification (Or if your pairwise coder comes up with something better). (Is that a good thing? or OverEngineering ?) I don't think it breaks LawOfDemeter 'because of using two dots', gathering from this page, the LOD seems to be less strict for 'primitive' datatypes like this. -- AnonymousStudent? (again!)

I agree with the student. A "dictionary with more than one index" is just a single-index dictionary with the index being a tuple of indices. --Salvatore


IsLawOfDemeterOverspecifiedOnCeeTwo


'Tis a silly law with diminishing returns on model complexity. Interesting, but irrelevant except in remarkably simple cases.

See ContractiveDelegation. --- I would tend to agree that going knee-deep in child calls etc is a bad idea, but one of the benefits of coding to an interface is that you know what you're getting back. It's not the name of the methods or properties that are significant in a contract... it's the type of interface (or primitive) that comes back. If that's specified in the contract, then it's safe to call a method of it.. say like .toString() (or ToString?(), depending on your flavor). This is true for unit testing as well since you're using the known contract... that's why we have them.. so we know what we're getting and what we can do with it. someone somewhere who takes this too literally is losing sight of what programs are for... and it's not to make pretty source code for programmers.

-- anonymous dave


An interesting corollary is: “Don't chain bang,” that is don't write ruby code like

list.flatten!.uniq!.compact!

The naive assumption is that each method would return the list, which was modified in place. But in fact, each method may return nil, causing the next method call to raise a NoMethodError?.

-- JosephHolsten?


CategoryModelingLawsAndPrinciples


EditText of this page (last edited December 3, 2014) or FindPage with title or text search