Groups | Search | Server Info | Keyboard shortcuts | Login | Register


Groups > comp.lang.java.programmer > #3735

Re: "Program to an interface" - When to break a design pattern

From Lew <noone@lewscanon.com>
Newsgroups comp.lang.java.programmer
Subject Re: "Program to an interface" - When to break a design pattern
Date 2011-05-06 21:39 -0400
Organization albasani.net
Message-ID <iq27rs$ehs$1@news.albasani.net> (permalink)
References <9dt5s6dalhetgfe99qs92c02hf0dbas44e@4ax.com> <iq139v$feg$1@news.onet.pl> <GR%wp.68076$yp3.20908@newsfe09.iad>

Show all headers | View raw


On 05/06/2011 07:53 PM, Arved Sandstrom wrote:
> On 11-05-06 12:15 PM, Michal Kleczek wrote:
>>   wrote:
>>
>>>
>>> I've seen this design pattern before
>>>
>>> http://witte-consulting.com/documents/design-principles/
>>>
>>> and, in general, I see the point of it.
>>>
>>> But say we've got something like this
>>>
>>> LinkedHashMap<String, Integer>  sortedMap = this.getSortedMap();
>>>
>>> So you have the method
>>>
>>> public LinkedHashMap<String, Integer>  getSortedMap() {
>>>    //do stuff
>>> }
>>>
>>> (not necessarily public)
>>>
>>> Now the design principle says, the method signature should instead be
>>>
>>> public Map<String, Integer>  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, 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.
>>>
>>> If nothing else, it's going to save Fred Developer down the line from
>>> looking at the code around this
>>>
>>> Map<String, Integer>  sortedMap = this.getSortedMap();
>>>
>>> and thinking "wait, how do I know getSortedMap() is going to return a
>>> result with the right ordering?", and having to waste time digging
>>> into that method.
>>>
>>> ***
>>>
>>> Opinions? Angry mob with torches and pitchforks? The Spanish
>>> Inquisition?
>>
>> Stick to the principle and specify return type as java.util.Map.
>
> It's best to understand that principle before urging it on people. No
> less an authority than Erich Gamma has made it clear - albeit not widely
> enough nor early enough - that when GOF said "program to an interface",
> they did *NOT* mean only Java "interface" as in a construct with the
> "interface" keyword. What they actually meant was the OOP interface that
> *every* class has, coupled with a judicious choice of which interface of
> this type to pick in the type hierarchy.
>
> What the principle really means - and you don't have to take my word for
> it, you can look up discussions by OOP authorities - is that given that
> the object you need is in a type hierarchy - classes, abstract classes,
> interfaces - that you pick that level in the type hierarchy to work
> with, which is as high up as possible while still meeting requirements.
>
> The highest interface that fits the bill might actually be the interface
> of a concrete class, or the interface of an abstract class. In fact
> abstract classes are frequently better as interfaces than actual Java
> "interfaces".
>
> Bear in mind - and this is not invented by me; you can find this if you
> keep up on OOP literature - that there is a reasonably well-known
> distinction also between public and published interfaces (look up
> "Fowler", "public", "published", and continue to keep in mind that
> "interface" doesn't mean the Java keyword). If an interface is published
> then it's not a bad thing to use it. LinkedHashMap has a published
> interface *and* it has behaviour that other maps do not have - it is a
> correct decision to stop in the type hierarchy with LinkedHashMap if
> that's the behaviour you need.
>
> 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.
>
>> The decision on what Map implementation to use has to obey DRY principle -
>> if the place to decide is getSortedMap() then the rest of the program should
>> assume getSortedMap() does the right thing.
>
> Good luck with that one. That's what a lot of Java code ends up hoping
> for, because people misunderstood "program to an interface" and forced
> the use of the highest possible level Java-keyword interfaces everywhere
> possible. There are a bunch of problems that come about then:
> downcasting all over the place, brittle code because now everything that
> relied on interface X (including the 10 classes you wrote that
> implemented it) has to be changed because you need to add a method to
> interface X (or modify a method signature in interface X), calling code
> unaware that it really ended up depending on that Map actually being a
> LinkedHashMap and only finding out when some other provider of the
> method gets swapped in...the list goes on and on.
>
>> Imagine the requirements change and from now on the map has to retain
>> reverse insertion order. Do you want to rewrite your clients?
>>
> Bad example in my opinion. The first time this happened I'd take it on
> the chin and accept that the client code doesn't know what it
> wants...seeing as how it's the client code that forces a change like
> this. And rather than be screwed twice I'd probably write an abstract
> class, or Java-keyword interface, that would let me cope with poor
> design by the other team.
>
> Be clear on this - you could have used a high-level Java "interface", as
> in the keyword type of interface. And the requirements change and now
> you need to modify the interface - you're just as hosed then, Michal.

Here are the relevant chapter titles from /Effective Java/, by Joshua Bloch:
Item 18: Prefer interfaces to abstract classes
Item 19: Use interfaces only to define types
Item 52: Refer to objects by their interfaces
Item 53: Prefer interfaces to reflection

Here he refers to the Java 'interface', not the more general term you just 
discussed.

Note that in the details of Item 52, Mr. Bloch covers using the more specific 
types when the contract (the GoF sense of "interface") calls for it:

"If appropriate interface types exist, then ... your program will be more 
flexible if you use the interface to refer to the object; if not, just use the 
least specific class in the class hierarchy that provides the required 
functionality."


-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

"Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-05 12:21 -0700
  Re: "Program to an interface" - When to break a design pattern Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-05-05 15:43 -0400
    Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-05 17:19 -0400
  Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-05 21:47 +0200
  Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 14:14 -0600
    Re: "Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-05 13:26 -0700
    Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-05 22:27 +0200
      Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 14:42 -0600
        Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-05 22:48 +0200
          Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 15:02 -0600
            Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 00:02 +0200
              Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-05 19:49 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 02:28 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-06 07:24 -0300
                Re: "Program to an interface" - When to break a design pattern Patricia Shanahan <pats@acm.org> - 2011-05-06 07:03 -0700
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-06 17:30 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 18:56 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-06 17:50 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 23:37 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-06 19:43 -0300
              Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 17:17 -0600
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 02:28 +0200
          Re: "Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-05 23:25 -0700
            Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-06 18:25 +0200
              Re: "Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-07 16:26 -0700
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-08 03:28 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-08 00:05 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-08 16:15 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-08 14:20 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-08 19:48 +0200
                Re: "Program to an interface" - When to break a design pattern markspace <-@.> - 2011-05-10 07:36 -0700
                Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-10 13:04 -0600
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-10 21:31 +0200
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-10 20:01 -0300
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-11 19:14 +0200
                Re: "Program to an interface" - When to break a design pattern Patricia Shanahan <pats@acm.org> - 2011-05-11 10:41 -0700
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-11 19:55 +0200
                Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-11 16:42 -0400
                Re: "Program to an interface" - When to break a design pattern Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-05-11 23:34 +0200
                Re: "Program to an interface" - When to break a design pattern "John B. Matthews" <nospam@nospam.invalid> - 2011-05-12 00:51 -0400
                Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-12 00:58 -0400
                Re: "Program to an interface" - When to break a design pattern Tom Anderson <twic@urchin.earth.li> - 2011-05-12 20:08 +0100
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-15 13:25 -0300
        Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-05 17:24 -0400
          Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 16:00 -0600
          Re: "Program to an interface" - When to break a design pattern Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> - 2011-05-06 15:01 +0300
            Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-06 12:17 -0400
              Re: "Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-07 16:28 -0700
    Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-05 17:21 -0400
      Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 15:58 -0600
        Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-05 18:18 -0400
      Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-05 19:20 -0300
        Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-05 18:23 -0400
          Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-05 20:17 -0300
  Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-05 18:26 -0300
  Re: "Program to an interface" - When to break a design pattern Steven Simpson <ss@domain.invalid> - 2011-05-05 22:57 +0100
    Re: "Program to an interface" - When to break a design pattern Tom Anderson <twic@urchin.earth.li> - 2011-05-05 23:29 +0100
      Re: "Program to an interface" - When to break a design pattern Steven Simpson <ss@domain.invalid> - 2011-05-06 13:30 +0100
        Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-06 12:19 -0400
    Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 16:41 -0600
      Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-05 20:47 -0300
  Re: "Program to an interface" - When to break a design pattern Roedy Green <see_website@mindprod.com.invalid> - 2011-05-05 16:41 -0700
    Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-05 22:47 -0600
    Re: "Program to an interface" - When to break a design pattern Zapanaz <http://joecosby.com/code/mail.pl@foo.com> - 2011-05-05 23:28 -0700
  Re: "Program to an interface" - When to break a design pattern Michal Kleczek <kleku75@gmail.com> - 2011-05-06 17:15 +0200
    Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-06 20:53 -0300
      Re: "Program to an interface" - When to break a design pattern Lew <noone@lewscanon.com> - 2011-05-06 21:39 -0400
        Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-07 00:56 -0300
      Re: "Program to an interface" - When to break a design pattern Michal Kleczek <kleku75@gmail.com> - 2011-05-08 12:24 +0200
        Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-08 13:42 -0300
          Re: "Program to an interface" - When to break a design pattern Michal Kleczek <kleku75@gmail.com> - 2011-05-09 11:04 +0200
            Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-09 19:33 -0300
              Re: "Program to an interface" - When to break a design pattern Michal Kleczek <kleku75@gmail.com> - 2011-05-10 15:51 +0200
                Re: "Program to an interface" - When to break a design pattern Jim Janney <jjanney@shell.xmission.com> - 2011-05-10 13:15 -0600
                Re: "Program to an interface" - When to break a design pattern Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-05-10 19:40 -0300

csiph-web