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: * You can play with yourself. * You can play with your own toys (but you can't take them apart), * You can play with toys that were given to you. * And you can play with toys you've made yourself. ---- Explanation in plain English: * Your method can call other methods in its class directly * Your method can call methods on its own fields directly (but not on the fields' fields) * When your method takes parameters, your method can call methods on those parameters directly. * When your method creates local objects, that method can call methods on the local objects. but * One should not call methods on a global object (but it can be passed as a parameter ?) * One should not have a chain of messages a.getB().getC().doSomething() in some class other than a's class. ----- ''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 * governs the communication structure within an object-oriented design * restricts message-sending statements in method implementations * only talk to your immediate friends * message target can only be one of the following objects: 1 the method's object itself (C++, Java, C#: this; Smalltalk: self, super; VB.NET: Me) 2 an object that is an argument in the method's signature 3 an object referred to by the object's attribute 4 an object created by the method 5 an object referred to by a global variable ''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 Find''''''Whatever''''''Visitor 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 Kind''''''Of() )'', My''''''Leaves''''''Are() and My''''''Composites''''''Are() 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: * Collections (as described above) * ValueObject''''''s (especially as I follow ValueObjectsShouldBeImmutable) * Factories (and any object that returns another object and does ''not'' keep its own reference to the returned object). So, in my code the Law of Demeter only applies to ReferenceObject''''''s 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. * ''Wikipedia is not a dictionary, but I'd be interested in what the connection with the goddess is.'' ** Taken from http://www.ccs.neu.edu/home/lieber/LoD.html: 2003 was the 15 Year Anniversary of the Law of Demeter: The Law of Demeter is a simple style rule for designing ObjectOriented systems. "Only talk to your immediate friends" is the motto. The style rule was first proposed at Northeastern University in the fall of 1987 and popularized in books by Booch, Budd, Coleman, Larman, Page-Jones, Rumbaugh and others. A 2000 book that describes it well is The Pragmatic Programmer by AndrewHunt and DavidThomas. The name "Law of Demeter" was chosen because the style rule was discovered while working on the The Demeter Project which ever since was strongly influenced by the Law of Demeter. The Demeter Project develops tools that make it easier to follow the Law of Demeter. (Demeter = Greek Goddess of Agriculture; grow software in small steps) For example, "only talk to your immediate friends that share the same concerns" leads to tools for Aspect-Oriented Software Development. I wonder CanLawOfDemeterBeRefactoredAutomatically? See also: EncapsulationIsHierarchical, TreeOrientedPerspective, TellDontAsk, ShieldPattern, CapabilityComputing, LawOfDemeterExample, AlternateHardAndSoftLayers, ShearingLayers. Other references: * http://www.ccs.neu.edu/home/lieber/LoD.html * http://www.enteract.com/~bradapp/docs/demeter-intro.html * [Lieberherr89] Lieberherr, Karl. J. and Holland, I. Assuring good style for object-oriented programs IEEE Software, September 1989, pp 38-48 * [Lieberherr96] Karl Lieberherr, Adaptive Object Oriented Software - The Demeter Method, PWS Publishing Co., Boston, 1996. ---- 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. * from the caller's point of view, the thing that you are interested in is "what does bar do?" * from Bar's point of view, I don't want people monkeying about with my contents without me knowing about it. Maybe bar always needs to do a thing before and after foo does something. 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>. Then when looking up you do dictionary.get(firstIndex).get(secondIndex). * Does this break LawOfDemeter * If so, what's the better way of doing it? 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>; 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' 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