Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!.POSTED!not-for-mail From: Steven Simpson Newsgroups: comp.lang.java.programmer Subject: Re: "Program to an interface" - When to break a design pattern Date: Thu, 05 May 2011 22:57:27 +0100 Organization: Aioe.org NNTP Server Lines: 65 Message-ID: <73jb98-ki2.ln1@news.simpsonst.f2s.com> References: <9dt5s6dalhetgfe99qs92c02hf0dbas44e@4ax.com> NNTP-Posting-Host: r+C7JLFxs5GRD6HZueZLYg.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.22) Gecko/20090605 Lightning/0.9 Thunderbird/2.0.0.22 Mnenhy/0.7.6.666 X-Notice: Filtered by postfilter v. 0.8.2 Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3606 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. 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.