Re: "Program to an interface" - When to break a design pattern
On 08/05/2011 19:20, Arved Sandstrom allegedly wrote:
On 11-05-08 11:15 AM, Daniele Futtorovic wrote:
Anyway, I've had enough of this.
Probably just as well. You can't convince everyone to do something
ill-advised.
Them's fighting words.
No, merely argumentative words. Like I said, Daniele, I respect your
opinion - you produce good posts and I read them carefully - but I am
not impressed by dismissive statements like "Anyway, I've had enough of
this". That translates to "whatever, I can't make these idiots see the
light, I'm washing my hands of them" in vernacular English. If you
happened to say that in a professional environment, say a developers'
meeting, you'd have a lot of pissed-off people.
It's actually a lot better to say something like "I believe I'm correct,
but I'm clearly not making my case; I'll leave the discussion at this
point". Lot more diplomatic.
I have spent quite some time arguing on this topic. I have repeatedly
made one point that I believe to be central, which you at some point
even acknowledged, but which nobody cared to take into account. Yes,
that vernacular is exactly how I meant it.
Show me a code example with a method, that is not a factory method; that
returns a LinkedHashMap instance; for which it matters to the caller
that the return type be declared as LinkedHashMap, rather than Map.
I don't know why you're excluding factory methods. In fact a factory
method would be amongst the most likely to declare the return as Map and
not as LinkedHashMap, so I wouldn't be likely to use one as an example
anyway.
"Factory method" in the sense of a method whose sole purpose is to
construct the instance.
E.g.
<U, V> LinkedHashMap<U, V> createNewMap(){
// Decide on initial cap. and load factor here
return new LinkedHashMap<U, V>( 42, 0.42 );
}
I don't think I need to invent a new example: the OP has already
provided one.
I'm asking you to. The following is the only thing resembling code the
OP provided:
LinkedHashMap<String, Integer> sortedMap = this.getSortedMap();
public LinkedHashMap<String, Integer> getSortedMap() {
//do stuff
}
This hardly qualifies.
Let's say he's got client class A (maybe a JSF backing
bean) that absolutely requires that the DataModel be loaded by a map
obeying this contract. I'll go further and say that if your requirements
are so tenuous and erratic that this specific requirement is going to
change a fair bit, that you've got bigger problems than how you declare
your collections types. From the sounds of what the OP said this is a
definite, solid, stable and essential requirement.
Provider class B with the method in question is tasked to supply the map
that obeys this "predictable iteration order" contract...namely a
LinkedHashMap.
You can absolutely declare that return value from the B.getMap() method
as a Map. You'll need to comprehensively Javadoc that method as a
result, even if it's not a public/published API method, because now Map
tells you very little. You'll also do well to comment the location of
the call so as to increase the likelihood that future maintenance in
class A doesn't ignore the special required nature of _that_ Map.
"Now Map tells you very little". This is the central point. As I have
argued all along, it tells you /no less/ than it being LinkedHashMap,
because, as you have acknowledged, the mere fact that the return type is
LinkedHashMap does not give you any conclusive insight into its
iteration order (predictability thereof).
In other words, there's no contractual element to this, therefore it
does not add to the contract. So you would have to document
comprehensively anyway.
Consequently, applying the more general rule that types ought to be as
broad as possible and as narrow as necessary, make the return type
java.util.Map and document comprehensively.
-.-
This is perhaps the sixth time I've written the same thing with a
different wording. If it still doesn't get through to anyone, then yes,
I'll declare pearls before swine. Sorry for not being 'diplomatic' more
than the first half a dozen tries.
--
DF.
An escaped convict once said to me:
"Alcatraz is the place to be"