The function foo() calls a function on object string s1, which returns s2 to be further processed in this function...This looks like violating the Demeter law since it calls functions on an object
returned by another function. If so then what should be the alternative?
void foo()
{
bletch b;
std::cout << b.Something.substr(0, 5); // Directly accessing a method of bletch's members is forbidden
}
However, the practical applications of the Law of Demeter are often limited. It is much more useful to work in terms of layered abstractions than strict adherence to LoD style. Rather than demanding that you never access nested members, for instance (which can become really impractical in real code), you build everything like layers of lasagna. One layer may access the layer below it, but no layer may access the layer above it. Reaching more than one layer down is permissible but should be minimized when it makes sense.
Now this triggered another question. If the data member Something is returned by getters as a reference which is the case of managed languages like C# or JAVA, then it's a violation of the Demeter law. However, in case of C++ where we can get a copy of the object it's not. So although both languages used getters, it's the language semantics that determines this kind of violation. Correct?
foo.GetSomething().bar(); // violation
foo.DoBarOnSomething(); // ok
This holds regardless of language semantics. It doesn't matter what GetSomething() returns (a value, a reference, a const reference) because the very existence of GetSomething() means you're violating the one-degree-of-separation clause of the Law of Demeter.
Remember, it is better to tell an object to do something to itself than to ask it for information so you can do the same operation externally.
Incorrect. The Law of Demeter isn't about whether the data you're accessing is a copy or a reference, it's about maintaining a coherent abstraction and limiting the impact of change.
I'm now more confused. In one of the text books, it says that calling a method on an object not created by the function itself violates the law.
In this case
Something s = obj.GetSomething();
s.DoSomething();
Now if "s" was a copy rather than a reference it would be an object created inside the caller method and hence does not violate the Demeter. Otherwise, it's manipulating "obj's" data member directly.