Path: csiph.com!x330-a1.tempe.blueboxinc.net!aioe.org!news.glorb.com!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!newsfe04.iad.POSTED!8ad76e89!not-for-mail From: Arved Sandstrom User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 Newsgroups: comp.lang.java.programmer Subject: Re: "Program to an interface" - When to break a design pattern References: <9dt5s6dalhetgfe99qs92c02hf0dbas44e@4ax.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Lines: 76 Message-ID: X-Complaints-To: abuse@newsgroups-download.com NNTP-Posting-Date: Mon, 09 May 2011 22:34:00 UTC Organization: Public Usenet Newsgroup Access Date: Mon, 09 May 2011 19:33:58 -0300 Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3879 On 11-05-09 06:04 AM, Michal Kleczek wrote: > Arved Sandstrom wrote: > >> On 11-05-08 07:24 AM, Michal Kleczek wrote: >>> Arved Sandstrom wrote: >>> >>>> Further note: behaviour isn't just a list of method signatures. It's >>>> also what the abstract class or concrete class actually does. Not *how* >>>> it does it - that's implementation - but what it does - that's >>>> contractual _behaviour_. Keeping insertion order for iterators is >>>> _behaviour_...using a doubly-linked list to accomplish that is >>>> implementation. >>> >>> I think this is the real point of the discussion - Java interfaces are >>> just too weak to express contracts. Note that there are many other >>> aspects beside iteration ordering that are important to the overall >>> solution but still not expressed (and not expressable) by interfaces: >>> concurrency guarantees, performance and memory usage characteristics etc. >>> Picking one aspect and trying to express it using Java types just does >>> not make sense. >> >> Agreed, partly. It can't be done with Java interfaces at all. It can - >> obviously - be done with the published API of abstract or concrete Java >> classes. > > Then it would be not "what" but "how". No, that's not necessarily so. Abstract classes and concrete classes provide both a "what" - an interface (as in contract, not Java keyword) - and an implementation. An abstract class with no method implementations actually ought to be a Java interface, but assuming we have one, it's 100% "what" and 0% "how". An abstract class may trend quite high, 70 or 80 or 90 percent, in "how", but it's still 100% in "what", assuming that we consider all the public methods to be part of a published API. Even a concrete class - again assuming that all of its public methods are part of a published API - is 100% in "what", and now 100% on "how" as well. An implemented published method in a concrete class is as much part of a contractual interface as a method signature in a Java interface. >> What we're really arguing about here is whether it's desirable to bind >> client code to provider contracts. It's clear that Map cannot enforce a >> behavioural contract, and that LinkedHashMap does. Rather than beat that >> to death, let's acknowledge that we have one camp that argues that we >> don't want to tie the caller to a behavioural provider contract, and >> another camp (me) that says that sometimes you do want and need to do >> this. > > 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. AHS