Re: Design question - methods calling methods
On Sun, 23 May 2010, Rhino wrote:
Lew <noone@lewscanon.com> wrote in news:ht9k22$rkl$1@news.albasani.net:
Rhino wrote:
In all honesty, I hadn't even thought of SortedMap when I wrote the
code again the other day. I just knew that I wanted the result to be
in alphabetical order, not random the way that
Locales.getAvailableLocales() provides them. The article on the Map
interface pointed out that TreeMap would assure that I had
alphabetical order so I went with that. Now that you've reminded me
about SortedMap, I can see the merit of it. It's not much different
than TreeMap but it does give those additional features,
WTF are you talking about? I got lost in your antecedent-free
pronouns. Are you referring to the methods in 'TreeMap' that are not
implementations of 'SortedMap' methods?
As for 'SortedMap' not being "much different [from] TreeMap', well
that makes perfect sense since 'TreeMap' implements 'SortedMap'.
OTOH, some might say that an interface in some ways is always "much
different" from a concrete class, but that difference is the basis of
the recommendation to move to a wider ("looser") type.
like range operations. I don't see those as being _necessary_ for my
humble little getLocales() method, which I'm really just writing for
myself, but some future user of the class could conceivably benefit
from those extra features. Or maybe _I_ will get a benefit from those
features a little further down the road! I've modified the code to
produced a SortedMap - just replaced all "Map" with "SortedMap", dead
easy! - and reran my unit tests. Naturally, they still worked fine.
You're the API writer. YOU dictate what "some future user" gets to
do.
Fair enough.
It's a best practice to add a lot of "potentially useful" cruft to a
type. Implement what you need now, and refactor later if the need
arises.
(I saw your amendment about the missing "not" in that paragraph.)
I probably tend to overbuild a lot of the time anyway, in the sense of
adding functionality that isn't all that likely to be used. My current
thread about the internationalization/localization is proof of that. I
tend to anticipate needs that others aren't sure will ever happen. Not
all the time of course; it's just a tendency, not an obsession ;-)
This is a universal tendency. Everyone has it to some extent. From what i
remember of the dim depths of time, i had it rather strongly when i was
starting out programming, although it manifested itself in writing
overcomplicated class hierarchies and mad epicyclic structures of composed
objects. Kent Beck once accused me of suffering from 'premature
abstraction'. I think it's common to suffer from it strongly when you
first start thinking about design, and to grow out of it in time. Well, or
to become an architect, architects being the Peter Pans of the programming
world.
Are you familiar with the difference between interfaces and classes?
I'm not sure how to answer that. I've read formal definitions of both
and have written both and gotten them to run. But even after all the
time I've spent writing Java - I started in 1997 but had a 4 year gap
that ended a few months back where I wrote no Java at all - I don't feel
solid on a lot of the theory. Maybe I'm expecting too much of myself but
I feel like I should know instantly and intuitively what the key
differences are between classes and interfaces and not have to wrestle
with "should I use an interface or class here". But maybe guys like you
and Eric and Tom have to think long and hard about that too. I really
don't know.
It's unusual to be in a situation where there is a real choice between a
class and an interface. When you're deciding the type of a variable, you
ask, as Lew said, "what is the most general type that guarantees the
behaviour i want from this variable". You don't worry about whether that
type is a class or an interface.
When you're designing an inheritance hierarchy to exploit polymorphism,
you can choose to make the root type an interface or an exposed base
class. Like:
public abstract class DataStore {
public abstract Data load(String id);
}
public class RelationalDataStore extends DataStore {
public Data load(String id) {
// code
}
}
vs
public interface DataStore {
public Data load(String id);
}
public class RelationalDataStore implements DataStore {
public Data load(String id) {
// code
}
}
The mainstream modern school of thought is that you should always choose
the interface, so there's no real dilemma there either.
tom
--
One horse laugh is worth a thousand syllogisms. -- H. L. Mencken