Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Jim Janney Newsgroups: comp.lang.java.programmer Subject: Re: "Program to an interface" - When to break a design pattern Date: Thu, 05 May 2011 16:41:54 -0600 Organization: As little as possible Lines: 76 Message-ID: <2p7ha4py6l.fsf@shell.xmission.com> References: <9dt5s6dalhetgfe99qs92c02hf0dbas44e@4ax.com> <73jb98-ki2.ln1@news.simpsonst.f2s.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx01.eternal-september.org; posting-host="dZdavj/jUDynNQgDq5jkeA"; logging-data="32286"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+nt5BnEG9EccuXOcJT9R+U" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:JML+PltGoJC0weKuc1kH5dBamKw= sha1:Xwy6h1IZkhhFVnA4/jh9o7ldFe0= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3617 Steven Simpson writes: > On 05/05/11 20:21, Zapanaz wrote: >> So you have the method >> >> public LinkedHashMap getSortedMap() { >> //do stuff >> } >> >> (not necessarily public) >> >> Now the design principle says, the method signature should instead be >> >> public Map getSortedMap() { >> //do stuff >> } >> >> The problem is, where I'm creating sortedMap above, I need the map to >> retain the insertion order. If what's returned actually is a Map, >> rather than a LinkedHashMap, > > (I'll assume that you meant "If what's returned is not an implementation > of LinkedHashMap...", rather than addressing the literal point.) > >> then the results the user actually sees >> are going to be in the wrong order. Making things worse, in this case, >> nothing would actually break, only the end user would notice anything >> was actually wrong. >> >> So in this case, it seems to me, that using LinkedHashMap in the >> method signature makes sense. The fact that the return retains the >> insertion order is an integral part of what the method does. > > I would say that it was still better just to use Map, as LinkedHashMap > need not be the only implementation with the predictable iteration that > the caller expects. Additional documentation is then required, of course. Good point. It turns out there's a LinkedMap in Apache Commons that also does this. > Hypothetically, what you might want is an intermediate interface between > Map and LinkedHashMap, e.g. InsertionOrderedMap, which extends Map but > adds no methods. This might provide some sort of compile-time > protection, that mere documentation cannot provide. > > However, IMHO, its value is dubious, for a few reasons: > > * An implementation of InsertionOrderedMap can be compiled without > meeting the insertion-order requirement. > * Another implementation of Map can be compiled without extending > InsertionOrderedMap while meeting the insertion-order requirement. > * Specifically for LinkedHashMap, it can actually provide access > order instead, so it couldn't implement both InsertionOrderedMap > and a similar AccessOrderedMap without breaking at least one > requirement, whichever way a particular instance was configured. > > OTOH, this sort of thing is already done, with Set and Collection. Set > extends Collection, but doesn't actually define any new methods. (It > does take advantage of 'overriding' the documentation, though.) Is it > worth having Set if: > > * you can implement Set without actually having set semantics? > * you can implement set semantics with just Collection? > > So, if you're prepared to trust that an implementation of Set or > InsertionOrderedMap follows the documented rules that can't be > compiler-enforced, perhaps it's as well do away with those interfaces, > and just put the documentation on methods like getSortedMap, and trust > that they are implemented accordingly. That may be the best overall approach. The Javadoc for java.util.Map explicitly notes that different implementations can provide different behavior here. -- Jim Janney