The problem here is the signature of setLocation
. It's stringly typed.
To elaborate: Why would it expect String
? A String
represents any kind of textual data. It can potentially be anything but a valid location.
In fact, this poses a question: what is a location? How do I know without looking into your code? If it were a URL
than I would know a lot more about what this method expects.
Maybe it would make more sense for it to be a custom class Location
. Ok, I wouldn't know at first, what that is, but at some point (probably before writing this.configuration.getLocation()
I would take a minute to figure out what it is this method returns).
Granted, in both cases I need to look some place else to understand, what is expected. However in the latter case, if I understand, what a Location
is, I can use your API, in the former case, if I understand, what a String
is (which can be expected), I still don't know what your API expects.
In the unlikely scenario, that a location is any kind of textual data I would reinterpret this to any kind of data, that has a textual representation. Given the fact, that Object
has a toString
method, you could go with that, although this demands quite a leap of faith from the clients of your code.
Also you should consider, that this is Java you're talking about, which has very few features by design. That's what's forcing you to actually call the toString
at the end.
If you take C# for example, which is also statically typed, then you would actually be able to omit that call by defining behavior for an implicit cast.
In dynamically typed languages, such as Objective-C, you don't really need the conversion either, because as long as the value behaves like a string, everybody is happy.
One could argue, that the last call to toString
is less a call, than actually just noise generated by Java's demand for explicitness. You're calling a method, that any Java object has, therefore you do not actually encode any knowledge about a "distant unit" and thereby don't violate the Principle of Least Knowledge. There is no way, no matter what getLocation
returns, that it doesn't have a toString
method.
But please, do not use strings, unless they are really the most natural choice (or unless you're using a language, that doesn't even have enums ... been there).
"Single Entry, Single Exit" was written when most programming was done in assembly language, FORTRAN, or COBOL. It has been widely misinterpreted, because modern languages do not support the practices Dijkstra was warning against.
"Single Entry" meant "do not create alternate entry points for functions". In assembly language, of course, it is possible to enter a function at any instruction. FORTRAN supported multiple entries to functions with the ENTRY
statement:
SUBROUTINE S(X, Y)
R = SQRT(X*X + Y*Y)
C ALTERNATE ENTRY USED WHEN R IS ALREADY KNOWN
ENTRY S2(R)
...
RETURN
END
C USAGE
CALL S(3,4)
C ALTERNATE USAGE
CALL S2(5)
"Single Exit" meant that a function should only return to one place: the statement immediately following the call. It did not mean that a function should only return from one place. When Structured Programming was written, it was common practice for a function to indicate an error by returning to an alternate location. FORTRAN supported this via "alternate return":
C SUBROUTINE WITH ALTERNATE RETURN. THE '*' IS A PLACE HOLDER FOR THE ERROR RETURN
SUBROUTINE QSOLVE(A, B, C, X1, X2, *)
DISCR = B*B - 4*A*C
C NO SOLUTIONS, RETURN TO ERROR HANDLING LOCATION
IF DISCR .LT. 0 RETURN 1
SD = SQRT(DISCR)
DENOM = 2*A
X1 = (-B + SD) / DENOM
X2 = (-B - SD) / DENOM
RETURN
END
C USE OF ALTERNATE RETURN
CALL QSOLVE(1, 0, 1, X1, X2, *99)
C SOLUTION FOUND
...
C QSOLVE RETURNS HERE IF NO SOLUTIONS
99 PRINT 'NO SOLUTIONS'
Both these techniques were highly error prone. Use of alternate entries often left some variable uninitialized. Use of alternate returns had all the problems of a GOTO statement, with the additional complication that the branch condition was not adjacent to the branch, but somewhere in the subroutine.
Thanks to Alexey Romanov for finding the original paper. See http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD249.PDF, page 28 (printed page number is 24). Not limited to functions.
Best Answer
Short answer: We don't. Both examples are absolutely fine.
There are three reasons why people use temporary variables anyway (like in your first example):
message
, not just any old string).