When is it ok to break "the law of demeter"? Any examples??
This is a hard question. Basically the law of demeter is more a convention than a strict rule. It is true that following it allows for a better OOP and results in a more decoupled code. In my experience, it's common to break this rule when you're working with User Interfaces. If you're creating your system from scratch, it's easier to attend this rule. Remember that like design patterns, this rule is not an absolute.
The only programming law I follow is KISS (Keep It Simple, Stupid or i prefer to call it, Keep it simply stupid).
At the end of the day what really matters is that: 1 - The software works. 2 - No bugs in it (or as minimal as possible) 3 - Your code is easy to read/understand and easy to modify.
So, I think that you might follow this or that convention, as long as it serves you, not the other way around.
It's okay to break any rule when you understand the consequences and are willing to either deal with the fallout or fix it. Usually that means living with it forever until you get fired or quit or refactor.
Usually people break rules without understanding higher goals or a more global context. That's when it is bad. Unfortunately, it takes discipline and experience to not break rules unnecessarily, and experience is not contagious.
MSN
Whenever it makes your code more readable / maintainable. The Law of Demeter is (IMHO) somewhat schizophrenic. On the one hand, it is extremely detailed. On the other hand, it's only a very general rule because in many contexts it simply doesn't apply. Method chaining may actually be a good thing. Consider the following builder class application (notice that in this code, each method actually returns a different type so this code violates the Law of Demeter).
Date date = Date.year(2009).month(1).day(1);
First, what are the advantages of such a pattern over the following construct?
Date date = new Date(2009, 1, 1);
- It improves readability,
- It improves compile-time type safety, and
- It allows
Date
very easily to be an immutable class which in itself has a lot of advantages.
Now, applying the Law of Demeter would yield code that is (again, IMHO) neither as readable nor as maintainable and simply offers not a single advantage over the terse form.
DateYearProxy y = Date.year(2009);
DateMonthProxy m = y.month(1);
Date date = m.day(1);
Discuss.
A common example would be an object that exposes a collection that is mutable.
e.g.: customerObject.Orders.Add(order);
it's not ok. ever. That's why it's the Law of Demeter, not the suggestion of Demeter.
Violators will be prosecuted. ;-)
In the shop I work at, the Law of Demeter is not even discussed. It doesn't exist.
We have a kind of intermediate API called ObjectLayer (dumb name but its stuck) that hosts the Object-Relational mapping. It uses lots of public properties, etc. It serves as the Model part of MVC. Part of the controller is grafted into ObjectLayer because it is programmable by the end user and needs to work on an alternate interface.
The GUI objects have references to the objects in ObjectLayer. These are passed around, manipulated almost at will, etc by the controller code attached to the GUI.
The mini-programming language is the only truly stable part of the interface. ObjectLayer stabalized in its form almost by accident because it works really well until someone tries to change it (not that the code is bad but half the developers have difficulty writing truly reusable code).
At some point in my career the pragmatic businessman in me started to have serious issues with the pragmatic programmer in me.
The sad truth is: If you are spending time worrying about The Law of Demeter, you are more than likely just wasting time/money. It's a good academic exercise, but only good in practice for a very limited subset of real world projects where attention to that level of design detail really matters.
Get it done, get it out the door, use it to generate revenue (monetary or otherwise). Any problems associated with the lack of adherence to The Law of Demeter can be filed under "problems I hope to have some day".
In short, almost always
Sorry to say but this is one law I had never heard of until this post and I don't think it is particularly widely followed in the programming community.
The wikipedia article wrote:
The guideline was invented at Northeastern University towards the end of 1987, and can be succinctly summarized as “Only talk to your immediate friends.” The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).
I don't see any reference here to the rule being followed in the agile community, in the most influential language design groups or any place else besides Northeastern University, illustrious school though it may be.
For example, on the c2 website, someone wrote
Before reading further please see LawOfDemeterVsInformationHiding, LawOfDemeterMakesUnitTestsEasier, LawOfDemeterIsHardToUnderstand, LawOfDemeterIsTooRestrictive, LawOfDemeterAndCoupling.
One case I've hit a few times where it would simply make a huge amount of stupid code:
Classes whose purpose is to round up a bunch of elements into some entity, say a customer's order.
Ok, there's an object in there for customer information. There's also one for the graphics. (CAD/CAM system) There's a third holding subdivisions in the order and these contain a fourth that are actually descriptions of the objects involved.
On the CAD side of things the descriptions of how to build the objects have virtually no effect outside the pricing engine--the rest of the program almost totally ignores the groups and works on the list of individual objects.
Note that these various data elements are virtually independent of each other, the top level container exists because there are cases where multiple plans can be loaded and the top level object contains things like I/O routines etc.
To provide routines to drill down into the various objects would be a huge waste of code. Many of the routines deal only with a smaller object and thus don't run afoul of the LoD but there are many cases where you simply need one piece of data that a couple of layers down--to provide ways around this would probably add 10k of code for no benefit other than complying with the LoD.
Suppose you have this:
function(foo) {
doSomethingWith(foo.bar.baz.fooBar);
// ...
}
then if you also
doSomethingElseWith(foo)
in the same function then maybe it's not too bad.
However, clearly if you never do anything with foo, but only use it to get to fooBar, then breaking the law is bad.
Another variation of the law is "don't look for things, ask for them". (Asking for them means "require them as arguments").
See here for a good discussion.