Browsing through some code I've written, I came across the following construct which got me thinking. At a first glance, it seems clean enough. Yes, in the actual code the
getLocation() method has a slightly more specific name which better describes exactly which location it gets.
In this case,
service is an instance variable of a known type, declared within the method.
this.configuration comes from being passed in to the class constructor, and is an instance of a class implementing a specific interface (which mandates a public
getLocation() method). Hence, the return type of the expression
this.configuration.getLocation() is known; specifically in this case, it is a
service.setLocation() wants a
String. Since the two types String and URL are not directly compatible, some sort of conversion is required to fit the square peg in the round hole.
However, according to the Law of Demeter as cited in Clean Code, a method f in class C should only call methods on C, objects created by or passed as arguments to f, and objects held in instance variables of C. Anything beyond that (the final
toString() in my particular case above, unless you consider a temporary object created as a result of the method invocation itself, in which case the whole Law seems to be moot) is disallowed.
Is there a valid reasoning why a call like the above, given the constraints listed, should be discouraged or even disallowed? Or am I just being overly nitpicky?
If I were to implement a method
URLToString() which simply calls
toString() on a
URL object (such as that returned by
getLocation()) passed to it as a parameter, and returns the result, I could wrap the
getLocation() call in it to achieve exactly the same result; effectively, I would just move the conversion one step outward. Would that somehow make it acceptable? (It seems to me, intuitively, that it should not make any difference either way, since all that does is move things around a little. However, going by the letter of the Law of Demeter as cited, it would be acceptable, since I would then be operating directly on a parameter to a function.)
Would it make any difference if this was about something slightly more exotic than calling
toString() on a standard type?
When answering, do keep in mind that altering the behavior or API of the type that the
service variable is of is not practical. Also, for the sake of argument, let's say that altering the return type of
getLocation() is also impractical.