Path: csiph.com!x330-a1.tempe.blueboxinc.net!aioe.org!goblin2!goblin.stu.neva.ru!plix.pl!newsfeed1.plix.pl!news.nask.pl!news.nask.org.pl!news.cyf-kr.edu.pl!agh.edu.pl!news.agh.edu.pl!news.onet.pl!.POSTED!not-for-mail From: Michal Kleczek Newsgroups: comp.lang.java.programmer Subject: Re: "Program to an interface" - When to break a design pattern Date: Tue, 10 May 2011 15:51:01 +0200 Organization: http://onet.pl Lines: 67 Message-ID: References: <9dt5s6dalhetgfe99qs92c02hf0dbas44e@4ax.com> NNTP-Posting-Host: 87-205-150-44.adsl.inetia.pl Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Trace: news.onet.pl 1305035461 4039 87.205.150.44 (10 May 2011 13:51:01 GMT) X-Complaints-To: niusy@onet.pl NNTP-Posting-Date: Tue, 10 May 2011 13:51:01 +0000 (UTC) User-Agent: KNode/4.4.9 Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3913 Arved Sandstrom wrote: > On 11-05-09 06:04 AM, Michal Kleczek wrote: >> I think you are missing the fact that the client is _already_ tied to a >> contract by calling getSortedMap() to get the map (since the contract of >> getSortedMap() is "return a map implementation that provides such and >> such iteration order". >> The question is rather - do we need to specify this contract as a Java >> type? I would rather say: since the compiler cannot enforce/check the >> contract anyway then it is useless - the contract specified as >> documentation of getSortedMap() is enough. >> > I agree that the compiler cannot enforce the contract unless both the > provider of the LinkedHashMap and the calling code are written > cooperatively to use LinkedHashMap explicitly, thereby locking in the > requirement. This is the scenario I've been positing. > > As I believe I mentioned in another post, you could get away with > documentation, but I believe you'd have to document not just the method, > but also all the call sites. If you're going to rely on documentation > then perhaps your biggest win would be to change the name of the method > - getMap() would be an atrocious choice. IMO the only defensible choice is > > Map getPredictableIterationOrderMap() > > Now *this* stands out when you're using it. Sure - naming of functions is one of the most important aspects of defining them. Anyway. Somehow I got lost in discussion and forgot the most important thing IMHO: the fact that iteration order is important to the overall solution does not imply it is important to the client code. Take an example: //the program is supposed to print hashcodes of strings provided as //arguments in the order that the user gave them //forget that the map is not needed here public void PrintHashes { public static void main(String[] args) { final Map mapOfHashes = new LinkedHashMap<>(); calculateHashes(Arrays.asList(args), mapOfHashes); printMap(mapOfHashes, System.out); } private static void calculateHashes( Iterable objects, Map hashes) { for (final Object object : objects) { hashes.put(object, object.hashCode()); } } private static void printMap(Map map, PrintStream out) { for (final Map.Entry entry : map.entrySet()) { out.println("Key: " + entry.getKey() + " Value: " + entry.getValue()); } } } According to your logic all references to Map should be replaced by LinkedHashMap which - sorry to say that - sounds insane :) -- Michal