Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Design question - methods calling methods

7 views
Skip to first unread message

Rhino

unread,
May 21, 2010, 4:20:05 PM5/21/10
to
Is it bad design for any reason for methods in one class to call other
methods in the same class to do some of their work for them? I'm pretty
sure the answer is no but this is just a sanity check to make sure I'm not
forgetting an important factor.

The situation that inspired the question is getLocales() method I've been
discussing in another thread. In addition to the getLocales() method, I
have a displayLocales() method. The displayLocales() method has no input
parameters and returns nothing, it simply writes to the console. It begins
by executing getLocales(), which returns a TreeMap, and then displays the
contents of the TreeMap on the console.

It seems absolutely reasonable to me that the getLocales() method gets
called to obtain the actual Locales, rather than repeating the code from
getLocales() again in displayLocales. If there is a problem with getLocales
(), it obviously affects BOTH methods but it only needs to be fixed in one
place to solve the problem for both methods which seems sensible to me.

I'm not nearly as familiar with source code of the Java API as some of you
seem to be but it seems to me that I've seen methods calling other methods
in some of my debugging in Eclipse too. So this is not a problem, right?

--
Rhino

Arne Vajhøj

unread,
May 21, 2010, 4:33:59 PM5/21/10
to
On 21-05-2010 16:20, Rhino wrote:
> Is it bad design for any reason for methods in one class to call other
> methods in the same class to do some of their work for them? I'm pretty
> sure the answer is no but this is just a sanity check to make sure I'm not
> forgetting an important factor.

It is very bad design never to do it.

Calling other methods is the standard way to keep the size of methods
down (and thereby improving readability).

Arne

Eric Sosman

unread,
May 21, 2010, 5:41:51 PM5/21/10
to
On 5/21/2010 4:20 PM, Rhino wrote:
> Is it bad design for any reason for methods in one class to call other
> methods in the same class to do some of their work for them? I'm pretty
> sure the answer is no but this is just a sanity check to make sure I'm not
> forgetting an important factor.

It's perfectly normal for one method to "re-use" another method's
code by calling that other method.

There is, however, one thing to watch out for. If the called
method can be overridden in a subclass, then the calling method
might not execute the code it wanted, but the subclass' code instead.
This may be all right (if a superclass calls hashCode() on an
instance of a subclass, it usually *wants* the subclass' hashCode()
and not its own), but can be surprising and perhaps troublesome if
you weren't expecting it. It's *especially* bad in a constructor,
where the superclass' constructor may wind up calling subclass code
before the subclass' constructor has finished!

Get a copy of "Effective Java" by Joshua Bloch, and read what
he says about designing for inheritance. Read the rest of the book,
too: It's good for the soul.

> The situation that inspired the question is getLocales() method I've been
> discussing in another thread. In addition to the getLocales() method, I
> have a displayLocales() method. The displayLocales() method has no input
> parameters and returns nothing, it simply writes to the console. It begins
> by executing getLocales(), which returns a TreeMap, and then displays the
> contents of the TreeMap on the console.

This seems reasonable. A subclass that overrides getLocales()
presumably does so because it wants to do something special, like
filter out Locales for which you don't have fonts installed. If so,
you'd presumably want to get the restricted Locale list rather than
the one the superclass would provide, so you'd want to use the
subclass' version of getLocales(). All seems well here -- but other
circumstances might be less benign.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Rhino

unread,
May 21, 2010, 7:22:19 PM5/21/10
to
Eric Sosman <eso...@ieee-dot-org.invalid> wrote in
news:ht6uo6$flf$1...@news.eternal-september.org:

> On 5/21/2010 4:20 PM, Rhino wrote:
>> Is it bad design for any reason for methods in one class to call
>> other methods in the same class to do some of their work for them?
>> I'm pretty sure the answer is no but this is just a sanity check to
>> make sure I'm not forgetting an important factor.
>
> It's perfectly normal for one method to "re-use" another method's
> code by calling that other method.
>

Good. At least I don't have to feel guilty for doing that :-)



> There is, however, one thing to watch out for. If the called
> method can be overridden in a subclass, then the calling method
> might not execute the code it wanted, but the subclass' code instead.
> This may be all right (if a superclass calls hashCode() on an
> instance of a subclass, it usually *wants* the subclass' hashCode()
> and not its own), but can be surprising and perhaps troublesome if
> you weren't expecting it. It's *especially* bad in a constructor,
> where the superclass' constructor may wind up calling subclass code
> before the subclass' constructor has finished!
>

Darn, always a gotcha lurking somewhere in the forest ;-)

> Get a copy of "Effective Java" by Joshua Bloch, and read what
> he says about designing for inheritance. Read the rest of the book,
> too: It's good for the soul.
>

I've heard a lot of good things about that book. Unfortunately, money is
tight right now so it's going to have to wait a bit. But I will try to
get it - and read it - when circumstances permit.....



>> The situation that inspired the question is getLocales() method I've
>> been discussing in another thread. In addition to the getLocales()
>> method, I have a displayLocales() method. The displayLocales() method
>> has no input parameters and returns nothing, it simply writes to the
>> console. It begins by executing getLocales(), which returns a
>> TreeMap, and then displays the contents of the TreeMap on the
>> console.
>
> This seems reasonable. A subclass that overrides getLocales()
> presumably does so because it wants to do something special, like
> filter out Locales for which you don't have fonts installed. If so,
> you'd presumably want to get the restricted Locale list rather than
> the one the superclass would provide, so you'd want to use the
> subclass' version of getLocales(). All seems well here -- but other
> circumstances might be less benign.
>

Okay, fair enough. Even the most reasonable of actions can have
unexpected consequences at times. I suppose that's a big part of the
reason we test as thoroughly as we can, to catch that kind of thing. You
can't anticipate EVERYTHING.


--
Rhino

Rhino

unread,
May 21, 2010, 7:23:40 PM5/21/10
to
Arne Vajh�j <ar...@vajhoej.dk> wrote in
news:4bf6ee28$0$285$1472...@news.sunsite.dk:

Good! I will do so whenever I can, in good conscience!
--
Rhino

Lew

unread,
May 21, 2010, 7:53:07 PM5/21/10
to
Rhino wrote:
>>> Is it bad design for any reason for methods in one class to call
>>> other methods in the same class to do some of their work for them?
>>> I'm pretty sure the answer is no but this is just a sanity check to
>>> make sure I'm not forgetting an important factor.

Arne Vajhøj wrote:
>> It is very bad design never to do it.
>>
>> Calling other methods is the standard way to keep the size of methods
>> down (and thereby improving readability).

Rhino wrote:
> Good! I will do so whenever I can, in good conscience!

Better would be to do so whenever it makes sense. Just because you can is not
a valid engineering justification.

--
Lew

Lew

unread,
May 21, 2010, 7:57:12 PM5/21/10
to
Rhino wrote:
> ... getLocales(), which returns a TreeMap, and then displays the

> contents of the TreeMap on the console.

It's mostly a good idea to declare variables as an interface type rather than
a concrete type. The rule of thumb is that you declare the variable with the
loosest possible type that has the behavioral contract you need.

Thus, you probably want 'getLocales()' to return a 'SortedMap', as someone
suggested in another thread, unless there's something specific about 'TreeMap'
in particular that requires you use only that type or a subtype thereof.

--
Lew

Arne Vajhøj

unread,
May 21, 2010, 8:14:50 PM5/21/10
to

Pick a good balance.

500 lines methods are not good.

But no methods > 3 lines is not good either.

Arne

Robert Klemme

unread,
May 22, 2010, 4:39:43 AM5/22/10
to

Adding to that: Depending on what DisplayLocales does it might be
reasonable to give it an argument of Iterable<Locale> so it can display
Locale instances regardless from where they were obtained. If
displayLocales() does extensive formatting of Locale instances for
display, you might even cut your methods differently. If, on the
contrary you just need this one way to obtain and display Locales it is
most reasonable to have it like OP did it.

It's not that there is the one and only reasonable solution to
distribution of functionality across methods but it always depends on
circumstance. Often this means that during the life time of an
application things need to be refactored to adjust to changed requirements.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Eric Sosman

unread,
May 22, 2010, 7:45:26 AM5/22/10
to
On 5/21/2010 7:22 PM, Rhino wrote:
> Eric Sosman<eso...@ieee-dot-org.invalid> wrote in
> news:ht6uo6$flf$1...@news.eternal-september.org:
>> [...]

>> Get a copy of "Effective Java" by Joshua Bloch, and read what
>> he says about designing for inheritance. Read the rest of the book,
>> too: It's good for the soul.
>>
> I've heard a lot of good things about that book. Unfortunately, money is
> tight right now so it's going to have to wait a bit. But I will try to
> get it - and read it - when circumstances permit.....

Excellent. Shouldn't take more than two or three years to
scrape together the thirty bucks.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Robert Klemme

unread,
May 22, 2010, 8:14:44 AM5/22/10
to

Lew

unread,
May 22, 2010, 11:05:17 AM5/22/10
to
On 05/22/2010 08:14 AM,
> On 22.05.2010 13:45,

>> On 5/21/2010 7:22 PM,
Eric Sosman wrote:
>>>> Get a copy of "Effective Java" by Joshua Bloch, and read what
>>>> he says about designing for inheritance. Read the rest of the book,
>>>> too: It's good for the soul.

Rhino wrote:
>>> I've heard a lot of good things about that book. Unfortunately, money is
>>> tight right now so it's going to have to wait a bit. But I will try to
>>> get it - and read it - when circumstances permit.....

Eric Sosman wrote:
>> Excellent. Shouldn't take more than two or three years to
>> scrape together the thirty bucks.

I wonder if the public library near Rhino has a copy, or if he knows *any*
other Java programmers.

Amazon lists used copies of the current edition from $36.92 used, up to $42.89
new. That'll break the bank!

Now all Rhino has to do is get together with three-Java programming friends
and share the cost. At under $13.25 each I feel quite sure Rhino can afford
to read the book, right, Rhino? Hm?

Or he could go to one of those bookstores with a coffee shop and read it in
the store for free.

The excuse "I can't afford it" is quite weak. Come on, Rhino. If you're
serious about Java programming you'll find a way to read this book, if no
other on the topic, and right soon.

Otherwise it's back to, "Would you like fries with that?"

--
Lew

Rhino

unread,
May 22, 2010, 3:53:58 PM5/22/10
to
Lew <no...@lewscanon.com> wrote in news:ht8rr2$noe$1...@news.albasani.net:

That's not as improbable as you probably think. And that's no joke. I am
indeed serious about Java but I have to eat and pay rent before I can
indulge the luxury of buying a book that I don't absolutely need right
now.... Once I'm gainfully employed again, things will look a lot
different.


--
Rhino

Rhino

unread,
May 22, 2010, 3:56:32 PM5/22/10
to
Lew <no...@lewscanon.com> wrote in news:ht76cp$dd3$3...@news.albasani.net:

Of course. I didn't mean to do it slavishly to the exclusion of common
sense....

--
Rhino

Lew

unread,
May 22, 2010, 4:12:20 PM5/22/10
to
Rhino wrote:
> That's not as improbable as you probably think. And that's no joke. I am
> indeed serious about Java but I have to eat and pay rent before I can
> indulge the luxury of buying a book that I don't absolutely need right
> now.... Once I'm gainfully employed again, things will look a lot
> different.

That's why I suggested free alternatives.

--
Lew

Rhino

unread,
May 22, 2010, 4:30:48 PM5/22/10
to
Lew <no...@lewscanon.com> wrote in news:ht76kf$e1c$1...@news.albasani.net:

For a second there, I had no idea what you were proposing.

But I reviewed the Collection Classes in the Java Tutorial and I think I
get it now.

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,
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.


Hmm. Did I do this right?

I had this:

=========================================================================
public Map<String, Locale> getLocales() {

Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
for (Locale oneLocale : Locale.getAvailableLocales()) {
sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
}

return sortedLocales;
}
========================================================================

and changed it to:

========================================================================
public SortedMap<String, Locale> getLocales() {

SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>();
for (Locale oneLocale : Locale.getAvailableLocales()) {
sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
}
return sortedLocales;
}
========================================================================

The first line of the revised method looks a bit funny:
SortedMap ... = TreeMap ....

Did I do what you meant?

Sigh! I still struggle with understanding what I am doing sometimes.... I
still don't REALLY understand the difference between these:

- Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();

- SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>
();

- Map<String, Locale> sortedLocales = new SortedMap<String, Locale>();

- and so forth

Or, by the same token:

- Calendar cal = Calendar.getInstance();
- Calendar cal = new GregorianCalendar();
- GregorianCalendar gcal = new GregorianCalendar();

If I had to write an exam, clearly articulating the distinction between
those and what the implications of each is, I'd surely make a hash of
it....

I can tell if I'm getting a compile error and I can tell if my code is
doing what I want it to do but I still don't always understand WHY one
thing is better than an other or what the real difference is between
things that look very very similar.....

That doesn't fill me with optimism about my ability to persuade an
employer that I would be a useful addition to their team. I imagine
they're going to want people that know that stuff backwards and
forwards....


--
Rhino

Roedy Green

unread,
May 22, 2010, 5:18:01 PM5/22/10
to
On Fri, 21 May 2010 20:20:05 +0000 (UTC), Rhino
<no.offline.c...@example.com> wrote, quoted or indirectly
quoted someone who said :

>Is it bad design for any reason for methods in one class to call other
>methods in the same class to do some of their work for them? I'm pretty
>sure the answer is no but this is just a sanity check to make sure I'm not
>forgetting an important factor.

As a general rule, avoid ever cloning code, unless it is just to get a
first cut before you brutally rehash it. You don't want snippets of
code repeated in your project. Sooner or later you will want to change
them, and it is impossible to ensure all are kept in sync.

If later you decide some of the clients need a variant and others do
not, it is lot easier to find all the occurrences if they have been
encapsulated.

The smaller your methods and the greater the reuse, the easier it is
to maintain code. You will only have to change one method. This is the
great truth you learn coding in FORTH.

--
Roedy Green Canadian Mind Products
http://mindprod.com

Beauty is our business.
~ Edsger Wybe Dijkstra (born: 1930-05-11 died: 2002-08-06 at age: 72)

Referring to computer science.

Jeff Higgins

unread,
May 22, 2010, 5:18:18 PM5/22/10
to
On 5/21/2010 4:20 PM, Rhino wrote:

> The situation that inspired the question is getLocales() method I've been
> discussing in another thread.

A recent post to this group prompts me to post these links:
<http://developers.sun.com/global/>
<http://developers.sun.com/global/technology/arch/>


Tom Anderson

unread,
May 22, 2010, 5:31:02 PM5/22/10
to
On Sat, 22 May 2010, Rhino wrote:

> Lew <no...@lewscanon.com> wrote in news:ht76kf$e1c$1...@news.albasani.net:
>
>> Rhino wrote:
>>> ... getLocales(), which returns a TreeMap, and then displays the
>>> contents of the TreeMap on the console.
>>
>> It's mostly a good idea to declare variables as an interface type
>> rather than a concrete type.

Rhino, read that sentence again.

>> The rule of thumb is that you declare the variable with the loosest
>> possible type that has the behavioral contract you need.

And that one.

And again.

Now proceed with the rest of this post.

>> Thus, you probably want 'getLocales()' to return a 'SortedMap', as
>> someone suggested in another thread, unless there's something specific
>> about 'TreeMap' in particular that requires you use only that type or
>> a subtype thereof.
>
> For a second there, I had no idea what you were proposing.
>
> But I reviewed the Collection Classes in the Java Tutorial and I think I
> get it now.
>
> 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.

You make that desire concrete by the type of the object holding the
locales - you want them to be sorted, so it's a SortedMap.

> 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, 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!

You're on the wrong track here. The extra features are not what SortedMap
is about - it's fundamentally about that first paragraph in its javadoc:

A Map that further provides a total ordering on its keys. The map is
ordered according to the natural ordering of its keys [...] This order is
reflected when iterating over the sorted map's collection views (returned
by the entrySet, keySet and values methods). Several additional
operations are provided to take advantage of the ordering.

Yes, there are several additional operations. But the heart of the matter
is that the map has an order, which governs iteration over its contents.

> 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.
>
> Hmm. Did I do this right?
>
> I had this:
>
> =========================================================================
> public Map<String, Locale> getLocales() {
>
> Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
> for (Locale oneLocale : Locale.getAvailableLocales()) {
> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
> }
>
> return sortedLocales;
> }
> ========================================================================
>
> and changed it to:
>
> ========================================================================
> public SortedMap<String, Locale> getLocales() {
>
> SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>();
> for (Locale oneLocale : Locale.getAvailableLocales()) {
> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
> }
> return sortedLocales;
> }
> ========================================================================

Spot on.

> The first line of the revised method looks a bit funny:
> SortedMap ... = TreeMap ....
>
> Did I do what you meant?

Yes. You did *exactly* what Lew meant when he said:

It's mostly a good idea to declare variables as an interface type rather
than a concrete type.

SortedMap is an interface type - it says 'this map is sorted somehow'.
TreeMap is a concrete type - it says 'this map is implemented as a
red-black tree, which incidentally results in it being sorted'.

> Sigh! I still struggle with understanding what I am doing sometimes.... I
> still don't REALLY understand the difference between these:
>
> - Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();

It happens to be a TreeMap, but all the type declares is that it's a map.

> - SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>();

It happens to be a TreeMap, but all the type declares is that it's a
sorted map.

> - Map<String, Locale> sortedLocales = new SortedMap<String, Locale>();

Illegal. SortedMap is an interface.

> Or, by the same token:
>
> - Calendar cal = Calendar.getInstance();
> - Calendar cal = new GregorianCalendar();
> - GregorianCalendar gcal = new GregorianCalendar();

Those last two examples are an exact analogue. The first one is a little
different - but a natural extension of the idea.

The third version says "I care that this is object is specifically a
GregorianCalendar. I am going to do things with it which specifically
would not work with any other kind of calendar.". There are times when you
might want to say that, but you would strive to be more general - in which
case you would use the second version, which says "I care that this object
is a Calendar, but i don't care which kind of calendar - it could be
Gregorian, Islamic, Japanese Imperial, Darian Jovian, etc". However, in
the second form, although you will proceed to write your code
calendar-agnostically, you are actually hardcoding the choice of
GregorianCalendar there. You could change it later, but you'd have to go
through your code and change the constructions. In the first form, you
push the calendar-agnosticism even into the creation itself - rather than
explicitly using a GregorianCalendar, you let Calendar decide what kind of
calendar should be used. Right now, that will presumably always be a
GregorianCalendar, but if at some point someone boots up your software on
Ganymede (the moon, not the Eclipse release), it should probably be
Darian, and by leaving the decision to Calendar.getInstance, you let that
happen without having to alter your code. You delegate the decision to
someone in a better position to make it.

Now, in this particular case, there is a major caveat: different types of
Calendar are not interchangeable in the way that different types of Map
are, because they represent different ideas. If you're using this Calendar
object to handle dates which are definitively in Gregorian (January,
February and all that), then you need an actual GregorianCalendar, and you
should declare your variables accordingly. To paraphrase Einstein,
"everything should be made as generic as possible, but no more so".

> If I had to write an exam, clearly articulating the distinction between
> those and what the implications of each is, I'd surely make a hash of
> it....

That would be a real mistake. You should be making a tree. Have you
learned NOTHING?

> I can tell if I'm getting a compile error and I can tell if my code is
> doing what I want it to do but I still don't always understand WHY one
> thing is better than an other or what the real difference is between
> things that look very very similar.....

The choice between Map and SortedMap here is not one of correctness. It's
one of design and style. Good design and style doesn't change the way code
runs, but it makes it easier to understand and modify. A huge part of the
business of software is understanding and modifying existing code, and so
good design and style are valuable. They're investment for the future,
rather than the here and now.

tom

--
build the roof with holes in

Lew

unread,
May 22, 2010, 5:58:43 PM5/22/10
to
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.

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.

If you need access the 'TreeMap' methods that aren't part of the 'SortedMap'
interface, then by all means declare the variable that needs that access as
'TreeMap', otherwise don't.

> Hmm. Did I do this right?
>
> I had this:
>
> =========================================================================
> public Map<String, Locale> getLocales() {
>
> Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
> for (Locale oneLocale : Locale.getAvailableLocales()) {
> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
> }
>
> return sortedLocales;
> }
> ========================================================================
>
> and changed it to:
>
> ========================================================================
> public SortedMap<String, Locale> getLocales() {
>
> SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>();
> for (Locale oneLocale : Locale.getAvailableLocales()) {
> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
> }
> return sortedLocales;
> }
> ========================================================================

Yes.

> The first line of the revised method looks a bit funny:
> SortedMap ... = TreeMap ....

LOL.

Since 'TreeMap' /is-a/ 'SortedMap', that's perfectly legit. You can, and
often should upcast without danger.

> Did I do what you meant?

Yes.

> Sigh! I still struggle with understanding what I am doing sometimes.... I
> still don't REALLY understand the difference between these:
>
> - Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();

This variable 'sortedLocales' only has access to features promised by the
'Map' interface, not the additional methods of the 'TreeMap' or 'SortedMap' types.

It's also named with a lie, because the code could change to assign an
unsorted 'Map' to the variable without causing a compiler error, thus creating
a problem at run time. You never want to push compile-time-avoidable mistakes
to run time.

> - SortedMap<String, Locale> sortedLocales = new TreeMap<String, Locale>
> ();

The variable 'sortedLocales' has access to the methods of 'SortedMap' but not
those of 'TreeMap' not in the 'SortedMap' type. The name is not a lie,
because any refactoring of the code must use a 'SortedMap' subtype to assign
to the variable.

> - Map<String, Locale> sortedLocales = new SortedMap<String, Locale>();

This is "codecrap" as Eric likes to call it. It will not compile.

Are you familiar with the difference between interfaces and classes?

> - and so forth

"So forth"? What "so forth"? What do you mean?

> Or, by the same token:

These examples are by no means "the same token".

> - Calendar cal = Calendar.getInstance();

This does not guarantee that you will get a 'GregorianCalendar' or any other
particular type of 'Calendar'.

> - Calendar cal = new GregorianCalendar();

This guarantees that 'cal' points to a 'GregorianCalendar', but the behaviors
specific to 'GregorianCalendar' but not 'Calendar' cannot be accessed through it.

> - GregorianCalendar gcal = new GregorianCalendar();

This guarantees that 'gal' points to a 'GregorianCalendar', and the behaviors
specific to 'GregorianCalendar' can be accessed through it.

> If I had to write an exam, clearly articulating the distinction between
> those and what the implications of each is, I'd surely make a hash of
> it....

cal.hashCode()

> That doesn't fill me with optimism about my ability to persuade an
> employer that I would be a useful addition to their team. I imagine
> they're going to want people that know that stuff backwards and
> forwards....

No.

Employers hire people at all levels of experience and knowledge, with
appropriate adjustments to compensation, depending on the mix they need for
their team. I know of very few projects that hire only virtuosos, and I've
worked on many that actually hired incompetent programmers.

Which last you aren't, BTW.

--
Lew

Lew

unread,
May 22, 2010, 6:03:05 PM5/22/10
to
Lew wrote:
> 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.

Darn it!

It's a best practice NOT to add a lot of cruft. NOT to.

Somehow I proofread best after I've embarrassed myself.

--
Lew

Rhino

unread,
May 22, 2010, 9:30:25 PM5/22/10
to
Tom Anderson <tw...@urchin.earth.li> wrote in
news:alpine.DEB.1.10.1...@urchin.earth.li:

Sorry, I phrased my remarks poorly. I know the range handling and all
that are more along the lines of bonus features; the order of the data
is, of course, the main thing.

>> 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.
>>
>> Hmm. Did I do this right?
>>
>> I had this:
>>
>> ======================================================================

>> === public Map<String, Locale> getLocales() {


>>
>> Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
>> for (Locale oneLocale : Locale.getAvailableLocales()) {
>> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
>> }
>>
>> return sortedLocales;
>> }
>> ======================================================================
>> ==
>>
>> and changed it to:
>>
>> ======================================================================

>> == public SortedMap<String, Locale> getLocales() {

I didn't actually try that; I just threw it out to illustrate how these
things sort of all blur together in my brain....

Thanks for clarifying the differences between the two groups of
statements I listed above. You did quite a nice job and I feel that I
have a little better grasp of it. But I'd be lying if I really felt I
have a really solid handle on things. I feel like it should all be more
obvious somehow and not require me to rack my brain each time this kind
of thing comes up to try to understand just what the key distinction is
between X and X'.....


>> If I had to write an exam, clearly articulating the distinction
>> between those and what the implications of each is, I'd surely make a
>> hash of it....
>
> That would be a real mistake. You should be making a tree. Have you
> learned NOTHING?

LOL!! Good one!


>
>> I can tell if I'm getting a compile error and I can tell if my code
>> is doing what I want it to do but I still don't always understand WHY
>> one thing is better than an other or what the real difference is
>> between things that look very very similar.....
>
> The choice between Map and SortedMap here is not one of correctness.
> It's one of design and style. Good design and style doesn't change the
> way code runs, but it makes it easier to understand and modify. A huge
> part of the business of software is understanding and modifying
> existing code, and so good design and style are valuable. They're
> investment for the future, rather than the here and now.
>

I'm fine with those general principles. I have done maintenance
programming and I have been handed badly written programs that made me
cringe just to look at them - as I'm sure we all have. I've always gone
the extra mile to make my code just as good as I was capable of making it
in every way that I could: make it work, make it clear, make it easy to
read, etc.

Thanks for your advice and your clear explanations, Tom! Much
appreciated!
--
Rhino

Rhino

unread,
May 22, 2010, 9:30:36 PM5/22/10
to

> On Sat, 22 May 2010, Rhino wrote:

Sorry, I phrased my remarks poorly. I know the range handling and all
that are more along the lines of bonus features; the order of the data
is, of course, the main thing.

>> 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.
>>
>> Hmm. Did I do this right?
>>
>> I had this:
>>
>> ======================================================================

>> === public Map<String, Locale> getLocales() {


>>
>> Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
>> for (Locale oneLocale : Locale.getAvailableLocales()) {
>> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
>> }
>>
>> return sortedLocales;
>> }

>> ======================================================================
>> ==
>>
>> and changed it to:
>>
>> ======================================================================

>> == public SortedMap<String, Locale> getLocales() {

I didn't actually try that; I just threw it out to illustrate how these

things sort of all blur together in my brain....

Thanks for clarifying the differences between the two groups of
statements I listed above. You did quite a nice job and I feel that I
have a little better grasp of it. But I'd be lying if I really felt I
have a really solid handle on things. I feel like it should all be more
obvious somehow and not require me to rack my brain each time this kind
of thing comes up to try to understand just what the key distinction is
between X and X'.....

>> If I had to write an exam, clearly articulating the distinction
>> between those and what the implications of each is, I'd surely make a
>> hash of it....
>
> That would be a real mistake. You should be making a tree. Have you
> learned NOTHING?

LOL!! Good one!


>
>> I can tell if I'm getting a compile error and I can tell if my code
>> is doing what I want it to do but I still don't always understand WHY
>> one thing is better than an other or what the real difference is
>> between things that look very very similar.....
>
> The choice between Map and SortedMap here is not one of correctness.
> It's one of design and style. Good design and style doesn't change the
> way code runs, but it makes it easier to understand and modify. A huge
> part of the business of software is understanding and modifying
> existing code, and so good design and style are valuable. They're
> investment for the future, rather than the here and now.
>

Lew

unread,
May 22, 2010, 9:37:28 PM5/22/10
to
On 05/22/2010 09:30 PM,
> in
> news:alpine.DEB.1.10.1...@urchin.earth.li:

Rhino wrote:
>>> - Map<String, Locale> sortedLocales = new SortedMap<String,
>>> Locale>();

Tom Anderson wrote


>> Illegal. SortedMap is an interface.

Rhino wrote:
> I didn't actually try that;

Clearly not.

> I just threw it out to illustrate how these things
> sort of all blur together in my brain....

You were advised not to do that. Strongly.

I strongly advise you, again!, to stick with SSCCEs until you stop making that
kind of mistake. That you have not learned your lesson about posting
uncompilable code is starting to make you look careless and lazy.

(Naturally this does not apply to posts that intentionally illustrate code
that does not compile, but such posts invariably include verbiage that
indicates that the code is intentionally illegal.)

--
Lew

Rhino

unread,
May 22, 2010, 9:51:27 PM5/22/10
to
Lew <no...@lewscanon.com> wrote in news:ht9k22$rkl$1...@news.albasani.net:

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 ;-)



> If you need access the 'TreeMap' methods that aren't part of the
> 'SortedMap' interface, then by all means declare the variable that
> needs that access as 'TreeMap', otherwise don't.
>
>> Hmm. Did I do this right?
>>
>> I had this:
>>
>> ======================================================================

>> === public Map<String, Locale> getLocales() {


>>
>> Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
>> for (Locale oneLocale : Locale.getAvailableLocales()) {
>> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
>> }
>>
>> return sortedLocales;
>> }

>> ======================================================================
>> ==
>>
>> and changed it to:
>>
>> ======================================================================

>> == public SortedMap<String, Locale> getLocales() {


>>
>> SortedMap<String, Locale> sortedLocales = new TreeMap<String,
>> Locale>(); for (Locale oneLocale : Locale.getAvailableLocales()) {
>> sortedLocales.put(oneLocale.getDisplayName(locale), oneLocale);
>> }
>> return sortedLocales;
>> }
>> ======================================================================
>> ==
>
> Yes.
>
>> The first line of the revised method looks a bit funny:
>> SortedMap ... = TreeMap ....
>
> LOL.
>
> Since 'TreeMap' /is-a/ 'SortedMap', that's perfectly legit. You can,
> and often should upcast without danger.
>
>> Did I do what you meant?
>
> Yes.
>

Good :-)

>> Sigh! I still struggle with understanding what I am doing
>> sometimes.... I still don't REALLY understand the difference between
>> these:
>>
>> - Map<String, Locale> sortedLocales = new TreeMap<String, Locale>();
>
> This variable 'sortedLocales' only has access to features promised by
> the 'Map' interface, not the additional methods of the 'TreeMap' or
> 'SortedMap' types.
>
> It's also named with a lie, because the code could change to assign an
> unsorted 'Map' to the variable without causing a compiler error, thus
> creating a problem at run time. You never want to push
> compile-time-avoidable mistakes to run time.
>
>> - SortedMap<String, Locale> sortedLocales = new TreeMap<String,
>> Locale> ();
>
> The variable 'sortedLocales' has access to the methods of 'SortedMap'
> but not those of 'TreeMap' not in the 'SortedMap' type. The name is
> not a lie, because any refactoring of the code must use a 'SortedMap'
> subtype to assign to the variable.
>
>> - Map<String, Locale> sortedLocales = new SortedMap<String,
>> Locale>();
>
> This is "codecrap" as Eric likes to call it. It will not compile.
>

I was just throwing that out to illustrate the way these similar-looking
bits of code sometimes blur together in my brain....



> 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.


>> - and so forth
>
> "So forth"? What "so forth"? What do you mean?
>

Just that I could imagine other variants on the same sort of statements.


>> Or, by the same token:
>
> These examples are by no means "the same token".
>

I didn't mean to suggest that the calendar examples had anything to do
with the Map examples, just that the three statements in each group LOOK
similar but have very important differences. Unfortunately, those
differences don't jump out at me when I see them used in examples or
whatnot. I feel like it should be dead obvious instantly why the
programmer wrote one or the other or what bad things would happen if I
changed one to the other. But that doesn't happen for me.

>> - Calendar cal = Calendar.getInstance();
>
> This does not guarantee that you will get a 'GregorianCalendar' or any
> other particular type of 'Calendar'.
>
>> - Calendar cal = new GregorianCalendar();
>
> This guarantees that 'cal' points to a 'GregorianCalendar', but the
> behaviors specific to 'GregorianCalendar' but not 'Calendar' cannot be
> accessed through it.
>
>> - GregorianCalendar gcal = new GregorianCalendar();
>
> This guarantees that 'gal' points to a 'GregorianCalendar', and the
> behaviors specific to 'GregorianCalendar' can be accessed through it.
>
>> If I had to write an exam, clearly articulating the distinction
>> between those and what the implications of each is, I'd surely make a
>> hash of it....
>
> cal.hashCode()
>

Good one :-)



>> That doesn't fill me with optimism about my ability to persuade an
>> employer that I would be a useful addition to their team. I imagine
>> they're going to want people that know that stuff backwards and
>> forwards....
>
> No.
>
> Employers hire people at all levels of experience and knowledge, with
> appropriate adjustments to compensation, depending on the mix they
> need for their team. I know of very few projects that hire only
> virtuosos, and I've worked on many that actually hired incompetent
> programmers.
>
> Which last you aren't, BTW.
>

Well thank you, that's a very nice thing to say. Maybe I just expect too
much of myself. I suppose there's a certain envy here. I see guys like
you and Eric and Tom explaining things so articulately to people like me
and I wish that I had the confidence in my own ability to be able to
answer those questions as well. But it feels like 95% of the people in
this group know a lot more than I do.....

Still, I'm going to learn a lot more hanging around here getting
questions answered by people who know their stuff than by hanging around
with people who know less than I do. I'll keep plugging away at it. Maybe
in a couple of years I'll feel a little more capable of answering the
kind of questions most people here ask....

Thanks for your help with this - and so many of my other questions!


--
Rhino

Patricia Shanahan

unread,
May 22, 2010, 11:14:28 PM5/22/10
to
Rhino wrote:
...

> 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 ;-)
...

I also get tempted to overbuild. When I started programming, there was
some justification, because making design changes in a large program was
difficult and risky.

These days, it is so easy to refactor that there is generally little
benefit to adding complexity that is not needed for immediate needs.

The exception is designing APIs that will be used in code outside your
control.

Patricia

Lew

unread,
May 22, 2010, 11:39:13 PM5/22/10
to
Lew wrote:
>> Are you familiar with the difference between interfaces and classes?

Rhino wrote:
> 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".

The Java tutorial describes the difference, but doesn't really address your
question, so I'll take a stab.

Interfaces are pure contract - they describe the signatures of the methods
that class instances must implement, but may not contain any method
implementation nor instance members. (It's also usually a bad idea to give
them 'static' members.)

Classes may contain some implementation, and must be completely implemented if
not 'abstract'.

A class can implement an interface - that is, it is a subtype of the interface
that fills in the missing implementation details.

So you can have an interface:

public interface Foo
{
public void fooishBehavior();
}

Notice the semicolon instead of a method body - no curly braces in the method.
It's a promise that there will be such a method in any class that implements
the interface.

You can have an implementing class:

public class FooImpl implements Foo
{
public void fooishBehavior()
{
}
}

The class's claim that it 'implements Foo' requires it to implement the 'Foo'
methods, or at least be an abstract class. We'll ignore abstract classes for
you to study on your own.

The interface is a type - this is the key. All subtype classes or interfaces
are necessarily also of that type. 'extends' and 'implements' both express a
subtype relationship, and a subtype thing /is-a/ thing of its parent types.
(Inheritance expresses /is-a/; membership, a.k.a. composition, expresses /has-a/.)

The key is to think in terms of types, not classes. Interfaces are pure
expressions of type, and classes express a way for the type to do something
actual.

Different implementors of an interface can do quite different things, but they
must do the things promised by the type they implement.

Think of "type" as a contract - it shall have these behaviors!

All implementors of 'Foo' above must implement (or pass on the responsibility
abstractly to implement) that 'fooishBehavior()' method. How they do so is up
to them.

Variables have a type - that's what's important. When you use a variable of
type 'Foo', all you really care about is to use its 'fooishBehavior()'.

You should not (usually - always the disclaimer) care how the thing does its
'fooishBehavior()'.

So you typically have a construct like

Foo foo = new FooImpl();

Since everything of a subtype ('FooImpl') /is-a/ thing of the supertype
('Foo'), this is legal, and since 'Foo' is the type you care about, this is
proper.

Later you might refactor the code. Perhaps you discover that
'FooImpl#fooishBehavior()' is not thread safe but you need it to be. However,
the logic of the program doesn't need to know that, only that 'foo' has the
method, safe or not. So you change that initialization to:

Foo foo = new ConcurrentFooImpl();

The rest of the program, knowing only that 'foo' is of type 'Foo', needs no
rewrite. The hidden secret of the refactored 'foo' buys you thread safety,
and the rest of the program needs no recompile. Magic!

This came up in a project where I worked when we substituted something like

Map <Foo, Bar> whatever = Collections.synchronizedMap(
new HashMap <Foo, Bar> () );

with

Map <Foo, Bar> whatever = new ConcurrentHashMap <Foo, Bar> ();

and got a huge boost in the program's performance.

--
Lew

Lew

unread,
May 22, 2010, 11:54:16 PM5/22/10
to
Lew wrote:
>> Are you familiar with the difference between interfaces and classes?

Rhino wrote:
> 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".

The Java tutorial describes the difference, but doesn't really address your


question, so I'll take a stab.

Interfaces are pure contract - they describe the signatures of the methods
that class instances must implement, but may not contain any method
implementation nor instance members. (It's also usually a bad idea to give
them 'static' members.)

Classes may contain some implementation, and must be completely implemented

(if not 'abstract').

Tom Anderson

unread,
May 23, 2010, 6:21:39 AM5/23/10
to

It does seem a lot easier to find mistakes after you've committed them to
the internet. Perhaps we should agree that this is our new advanced
posting technique - post a rough draft first, then post the edits when you
realise what the mistakes are!

tom

--
One horse laugh is worth a thousand syllogisms. -- H. L. Mencken

Tom Anderson

unread,
May 23, 2010, 6:48:16 AM5/23/10
to

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.

Arne Vajhøj

unread,
May 23, 2010, 9:35:48 AM5/23/10
to

API's is a problem because you the most optimal refactoring may
expose an incompatible API.

But I believe that there are also other cases where refactoring
is not so easy.

One example is the topic of the thread. Internationalizing an
existing app is not difficult, but it is usually a lot of work.

I18N is a well-known counter-argument to YAGNI.

Arne


Arne Vajhøj

unread,
May 23, 2010, 9:57:33 AM5/23/10
to
On 23-05-2010 06:48, Tom Anderson wrote:
> On Sun, 23 May 2010, Rhino wrote:
>> 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.

http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html

I would word it a little bit different: abstraction is good - *IF* it
serves a purpose.


> Well,
> or to become an architect, architects being the Peter Pans of the
> programming world.

:-)

I think that is exaggarating.

Inheriting from abstract base classes is used all over the
Java API.

Joshua Bloch used the word "Prefer" in this context.

Sometimes is do make sense to reuse implementation functionality
(which is what the abstract base class offers).

Quite frequently a compromise is used with both an interface
and an abstract base class. This means that the 95% can
extend and only implement the few methods they need, but
still allow the remaining 5% to implement the interface
with full flexibility.

Arne


Rhino

unread,
May 23, 2010, 2:53:27 PM5/23/10
to
Lew <no...@lewscanon.com> wrote in news:hta0s6$dmk$1...@news.albasani.net:

> On 05/22/2010 09:30 PM,
>> in
>> news:alpine.DEB.1.10.1...@urchin.earth.li:
>
> Rhino wrote:
>>>> - Map<String, Locale> sortedLocales = new SortedMap<String,
>>>> Locale>();
>
> Tom Anderson wrote
>>> Illegal. SortedMap is an interface.
>
> Rhino wrote:
>> I didn't actually try that;
>
> Clearly not.
>
>> I just threw it out to illustrate how these things
>> sort of all blur together in my brain....
>
> You were advised not to do that. Strongly.
>
> I strongly advise you, again!, to stick with SSCCEs until you stop
> making that kind of mistake. That you have not learned your lesson
> about posting uncompilable code is starting to make you look careless
> and lazy.
>

Honestly, I think you're being just a little too rigid now.

I was trying to get across the idea that, at first glance, Map<String,
Locale> sorted Locales = new SortedMap<String, Locale>() might be
something I would CONSIDER writing to address the suggestion that was
made to me. I was trying to get across the idea that these statements all
start to look alike and interchangeable at some point, at least to me. I
know that this is not actually the case but it SEEMS like it sometimes.
Fundamentally, I'm just expressing frustration with myself that it isn't
more intuitive by now which of these statements is the one to use and
which ones don't even make sense.

I know (now) that the statement in question wouldn't actually compile or
make sense and I didn't actually try to compile it anywhere. It was
strictly a hypothetical and I truly think it is reasonable to toss out a
hypothetical now and again even if it is only to dismiss it very quickly
as the responders rightly did. I will continue to do that - very
sparingly I expect - and do so at my own peril. Maybe some of you will
disgusted with me for doing so and stop responding to me. If so, that's
life. I'll do what penance is needed to get back into everyone's good
graces or move on to some other discussion group if I have to.


> (Naturally this does not apply to posts that intentionally illustrate
> code that does not compile, but such posts invariably include verbiage
> that indicates that the code is intentionally illegal.)
>


--
Rhino

Rhino

unread,
May 23, 2010, 2:55:45 PM5/23/10
to
Arne Vajh�j <ar...@vajhoej.dk> wrote in news:4bf92f34$0$273$14726298
@news.sunsite.dk:

YAGNI? Sorry, I don't know that acronym.....

--
Rhino

Lew

unread,
May 23, 2010, 3:21:05 PM5/23/10
to
Rhino wrote:
>>> I just threw it out to illustrate how these things
>>> sort of all blur together in my brain....

Lew wrote:
>> You were advised not to do that. Strongly.
>>
>> I strongly advise you, again!, to stick with SSCCEs until you stop
>> making that kind of mistake. That you have not learned your lesson
>> about posting uncompilable code is starting to make you look careless
>> and lazy.

Rhino wrote:
> Honestly, I think you're being just a little too rigid now.

You aren't being "rigid" enough.

> I was trying to get across the idea that, at first glance, Map<String,
> Locale> sorted Locales = new SortedMap<String, Locale>() might be
> something I would CONSIDER writing to address the suggestion that was

You should never "CONSIDER" writing 'new SomeInterface()'.

> I know (now) that the statement in question wouldn't actually compile or
> make sense and I didn't actually try to compile it anywhere. It was

You should have done.

> strictly a hypothetical and I truly think it is reasonable to toss out a
> hypothetical now and again even if it is only to dismiss it very quickly

Not if it's blatantly ridiculous like 'new SomeInterface()' which on the very
face of it is obviously wrong.

> as the responders rightly did. I will continue to do that - very
> sparingly I expect - and do so at my own peril. Maybe some of you will
> disgusted with me for doing so and stop responding to me. If so, that's
> life. I'll do what penance is needed to get back into everyone's good
> graces or move on to some other discussion group if I have to.

What the hell does anyone's "good graces" have to do with it?

We're, or at least I'm trying to provide information and advice that will help
you!

Now you petulantly whine that you're going continue to engage in bad practices
out of some bizarre obstinacy.

This only hurts yourself. It's not a question of anyone else's opinion but of
how you can best serve yourself in your attempt to progress as a developer.

You disregard the advice "at [your] own peril", all right, but it's not a
social peril, it's the peril that you'll never get any better as a software
developer.

I strongly advise you to get off your high horse about this issue.

"Penance". WTF?

--
Lew

Rhino

unread,
May 23, 2010, 3:29:14 PM5/23/10
to
Lew <no...@lewscanon.com> wrote in news:hta80e$l5b$1...@news.albasani.net:

No worries; I've created and used some abstract classes in the past. I
was going to say they seemed quite straightforward but maybe I should
look into them again, just to make sure I'm not failing to consider
important aspects! But I'll do that on my own and post if I have
questions.

Having already read your note twice, I'm starting to have trouble
distinguishing between an interface that contains an abstract method and
an abstract class that has an abstract method. But I should probably mull
this over a bit more before attempting any followup questions. I don't
think I understand the interface thoroughly yet so no point in muddying
the waters with abstract classes just yet....

> The interface is a type - this is the key. All subtype classes or
> interfaces are necessarily also of that type. 'extends' and
> 'implements' both express a subtype relationship, and a subtype thing
> /is-a/ thing of its parent types. (Inheritance expresses /is-a/;
> membership, a.k.a. composition, expresses /has-a/.)
>
> The key is to think in terms of types, not classes. Interfaces are
> pure expressions of type, and classes express a way for the type to do
> something actual.
>
> Different implementors of an interface can do quite different things,
> but they must do the things promised by the type they implement.
>
> Think of "type" as a contract - it shall have these behaviors!
>
> All implementors of 'Foo' above must implement (or pass on the
> responsibility abstractly to implement) that 'fooishBehavior()'
> method. How they do so is up to them.

So, because Set is an interface, all of its implementors, including
HashSet, LinkedHashSet and TreeSet, need to implement all of its (non-
abstract) methods. But HashSet can implement the contains() method
differently than TreeSet does if that seems advisable.


> Variables have a type - that's what's important. When you use a
> variable of type 'Foo', all you really care about is to use its
> 'fooishBehavior()'.
>

I always tend to think of variables as things like

String greeting = "Hello";

from my COBOL days. But you're using variable where I might say instance,
right? As in this case, where the variable myform is being instantiated:

Form myForm = new Form();

I'm pretty sure you mean the latter because 'myForm' in this case
presumably has some number of behaviours (methods) to do this and that.
Then again, by virtue of being a String, 'fred' has behaviours too, such
as length() and substring(). Hmm, maybe this is a "distinction without a
difference". After all,

String greeting = "Hello";

is equivalent to:

String greeting = new String("Hello");


> You should not (usually - always the disclaimer) care how the thing
> does its 'fooishBehavior()'.
>
> So you typically have a construct like
>
> Foo foo = new FooImpl();
>
> Since everything of a subtype ('FooImpl') /is-a/ thing of the
> supertype ('Foo'), this is legal, and since 'Foo' is the type you care
> about, this is proper.
>

Or, to use an example from the API:

Set<String> mySet = new TreeSet<String>();

Would you consider that a parallel example? In other words, in your
example, was Foo an interface while FooImpl was a class?


> Later you might refactor the code. Perhaps you discover that
> 'FooImpl#fooishBehavior()' is not thread safe but you need it to be.
> However, the logic of the program doesn't need to know that, only that
> 'foo' has the method, safe or not. So you change that initialization
> to:
>
> Foo foo = new ConcurrentFooImpl();
>

Since I'm not 100% sure whether you mean Foo to be an interface or a
class, let me just ask if you're saying that your example is logically
equivalent to changing:

Set<String> mySet = new TreeSet<String>();

to

Set<String> mySet = new HashSet<String>();

In my example, you may have decided that the performance benefits of the
HashSet outweigh the fact that your data is in alphabetical order within
the TreeSet.

> The rest of the program, knowing only that 'foo' is of type 'Foo',
> needs no rewrite. The hidden secret of the refactored 'foo' buys you
> thread safety, and the rest of the program needs no recompile. Magic!
>
> This came up in a project where I worked when we substituted something
> like
>
> Map <Foo, Bar> whatever = Collections.synchronizedMap(
> new HashMap <Foo, Bar> () );
>
> with
>
> Map <Foo, Bar> whatever = new ConcurrentHashMap <Foo, Bar> ();
>
> and got a huge boost in the program's performance.
>

You have to love it when a one line change makes a big improvement like
that :-)

--
Rhino

Lew

unread,
May 23, 2010, 3:57:22 PM5/23/10
to
Arne Vajhøj wrote:
>> I18N is a well-known counter-argument to YAGNI.

Rhino:


> YAGNI? Sorry, I don't know that acronym.....

<http://www.google.com/search?q=YAGNI+acronym>

GIYF. Sometimes you should put in a little effort yourself.

--
Lew

Rhino

unread,
May 23, 2010, 4:32:10 PM5/23/10
to

> On Sun, 23 May 2010, Rhino wrote:

I remember a first year Algebra course at university where the professor
couldn't say ANYTHING without making it as abstract as humanly possible.
Where you or I might say "1 + 1 = 2", he'd write something like " N,
where it is a member of a universe of possible number systems which may
include integers, when added to X, where it is a member of a universe of
a possible number systems which may include integers, may result in Z,
where it is a member of a universe of possible number systems which may
include integers". Or something like that anyway. And of course he'd
write it on the board in proper algebraic notation which I've long
forgotten. The abstractions, which I'm grossly oversimplifying, made his
point, which was probably very simple, so obscure that I was utterly lost
within moments of him starting. I struggled as best I could for a couple
of weeks or so but I was so completely lost, I realized I would fail very
badly if I stayed in this class. I soon found another algebra course,
taught by a prof who was far less abstract, and was fine. As insightful
and interesting as the first prof's abstractions probably were, they were
way beyond anything I could follow at the time ;-) (For what it's worth,
a friend who knew others in the class said that a very large percentage
of the rest of the students in that class said virtually all of them had
dropped the course not long after I did. I hope they prof learned to be a
little more concrete from that experience :-)


>>> 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.
>

Sorry, I probably put my initial remarks badly.

Sigh. I've accumulated a number of confusions over my time with Java.
Sometimes, I can put them aside and still get by just fine. Sometimes, I
think I've finally seen the light and understand the obscure point for a
while, but then an example or a remark a newsgroup like this makes me
wonder if I understood the point correctly after all. And of course I'm
not sufficiently disciplined to actually write all of these confusions
down or to systematically resolve them via research and/or newsgroup
questions.....

I'm pretty sure that one of those fundamental confusions was on my mind
when I made my very general remark about confusion between interfaces and
classes but since I truly can't think of anything specific, and since I
don't have the time right now to mentally reconstruct and type my List of
Java Confusions for you, let's just put all that aside for some other
time.

Right now, I think I would benefit from the answer to a new mystery.

I do database stuff fairly frequently and mostly use my copy of DB2 as my
database engine. Naturally, I use ResultSets for a lot of this work. I
know that ResultSet is an interface, not a class, but it is rich in
exactly the sorts of methods I need to grab the Strings, integers and
whatnot in the database or to write them to the database. A short time
ago, I was looking at the source for ResultSet and found that not one of
the many methods in that interface are implemented; every single method
seems to be abstract. I see in the JavaDoc that there are a number of
"sub-interfaces" - I'm really not sure what a sub-interface is and how it
is different from a interface and that it has a "super-interface" -
again, I'm not sure what that is! - but the perplexing thing is that I am
not explicitly using the super-interface or any of the sub-interfaces yet
my code still works fine. That kind of thing disorients me; I wonder how
that could possibly be working and why I don't need to change from
ResultSet to a real class or another sub-interface or whatever. My
pragmatic self is capable of just ignoring all of that and saying "It's a
mystery but I'm not going to question it since it obviously works." But
my more idealistic self is bothered that it isn't obvious to me why the
ResultSet works despite its troubling aspects.

Can you possibly shed some light on what is happening there?

> 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.
>

Okay. That seems clear enough :-)

--
Rhino

Lew

unread,
May 23, 2010, 4:43:51 PM5/23/10
to
Lew wrote:
>>>> Are you familiar with the difference between interfaces and classes?
...

>> The class's claim that it 'implements Foo' requires it to implement
>> the 'Foo' methods, or at least be an abstract class. We'll ignore
>> abstract classes for you to study on your own.

Rhino wrote:
> Having already read your note twice, I'm starting to have trouble
> distinguishing between an interface that contains an abstract method and
> an abstract class that has an abstract method. But I should probably mull
> this over a bit more before attempting any followup questions. I don't
> think I understand the interface thoroughly yet so no point in muddying
> the waters with abstract classes just yet....

An interface MUST NOT have any implementation of its methods. It's pure type.

An abstract class MAY have implementation for any or all of its methods. It's
type with some implementation.

A type may inherit (extend or implement) any number of interfaces. A class
may only extend from one class.

Lew wrote:
>> The key is to think in terms of types, not classes. Interfaces are
>> pure expressions of type, and classes express a way for the type to do
>> something actual.

Rhino wrote:
> So, because Set is an interface, all of its implementors, including
> HashSet, LinkedHashSet and TreeSet, need to implement all of its (non-
> abstract) methods.

There are no non-abstract methods in an interface.

> But HashSet can implement the contains() method
> differently than TreeSet does if that seems advisable.

Correct.

Rhino wrote:
> I always tend to think of variables as things like
>
> String greeting = "Hello";
>
> from my COBOL days. But you're using variable where I might say instance, right?

No.

An instance is the object itself. A variable is a pointer to the instance.

> As in this case, where the variable myform is being instantiated:
>
> Form myForm = new Form();

No, the variable is being initialized. The instance is being instantiated.
("Instance", "instantiate" - see the connection?)

> I'm pretty sure you mean the latter because 'myForm' in this case
> presumably has some number of behaviours (methods) to do this and that.

No, the instance has behaviors. The variable only gives you access to invoke
those behaviors.

> Then again, by virtue of being a String, 'fred' has behaviours too, such
> as length() and substring(). Hmm, maybe this is a "distinction without a
> difference". After all,

I don't know what you're talking about here. Again, the variable does not
have behaviors, it only gives you (possibly limited) access to those behaviors
by pointing to the object that actually does have the behaviors (and possibly
others to which the variable does not give access).

>
> String greeting = "Hello";
>
> is equivalent to:
>
> String greeting = new String("Hello");

No, those are not at all equivalent.

> Or, to use an example from the API:
>
> Set<String> mySet = new TreeSet<String>();
>
> Would you consider that a parallel example? In other words, in your
> example, was Foo an interface while FooImpl was a class?

Did you actually *read* the sample code I provided for 'Foo' and 'FooImpl'?
The answer is there:


>> So you can have an interface:
>>
>> public interface Foo
>> {
>> public void fooishBehavior();
>> }

...


>> You can have an implementing class:
>>
>> public class FooImpl implements Foo
>> {
>> public void fooishBehavior()
>> {
>> }
>> }

Tch, tch.

Rhino wrote:
> Since I'm not 100% sure whether you mean Foo to be an interface or a
> class, let me just ask if you're saying that your example is logically

I really don't get how you aren't. I get the feeling you aren't paying attention.

> equivalent to changing:
>
> Set<String> mySet = new TreeSet<String>();
>
> to
>
> Set<String> mySet = new HashSet<String>();
>
> In my example, you may have decided that the performance benefits of the
> HashSet outweigh the fact that your data is in alphabetical order within
> the TreeSet.

What performance benefits?

Given that you need results in sorted order, you are nearly certain not to
have any. Even without that, what performance benefits?

Performance is never an argument that wins over logical correctness.

"I can give you wrong answers in half the time of correct ones!"

--
Lew

Eric Sosman

unread,
May 23, 2010, 4:42:16 PM5/23/10
to
On 5/23/2010 2:53 PM, Rhino wrote:
> Lew<no...@lewscanon.com> wrote in news:hta0s6$dmk$1...@news.albasani.net:
>>
>> I strongly advise you, again!, to stick with SSCCEs until you stop
>> making that kind of mistake. That you have not learned your lesson
>> about posting uncompilable code is starting to make you look careless
>> and lazy.
>>
> Honestly, I think you're being just a little too rigid now.

Rhino, you are asking strangers for free help, free advice,
free assistance. Said strangers are accustomed to being paid for
exercising their expertise, but for reasons of their own they put
it at your disposal gratis. Under the circumstances, you are in
no position to dictate terms, much less to insist that they put
up with your persistent (intentional?) sloppiness.

If you'll play by my rules, I'm willing to try to help. But
if you insist on mocking them, I'll take my ball and go home.
Other potential helpers will have different preferences, and
different sticking points -- but sooner or later, you will have
to do things their way or pay them enough to put up with you.
Can't speak for others, but as for me: Mend your ways, or I will
go mine.

Beggars can't be choosers.

TANSTAAFL.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Lew

unread,
May 23, 2010, 4:54:02 PM5/23/10
to
Please trim your posts.

Rhino wrote:
> Right now, I think I would benefit from the answer to a new mystery.

Should have a new thread, then.

> I do database stuff fairly frequently and mostly use my copy of DB2 as my
> database engine. Naturally, I use ResultSets for a lot of this work. I
> know that ResultSet is an interface, not a class, but it is rich in
> exactly the sorts of methods I need to grab the Strings, integers and
> whatnot in the database or to write them to the database. A short time
> ago, I was looking at the source for ResultSet and found that not one of
> the many methods in that interface are implemented; every single method
> seems to be abstract. I see in the JavaDoc that there are a number of
> "sub-interfaces" - I'm really not sure what a sub-interface is and how it
> is different from a interface and that it has a "super-interface" -
> again, I'm not sure what that is! - but the perplexing thing is that I am
> not explicitly using the super-interface or any of the sub-interfaces yet
> my code still works fine. That kind of thing disorients me; I wonder how
> that could possibly be working and why I don't need to change from
> ResultSet to a real class or another sub-interface or whatever. My
> pragmatic self is capable of just ignoring all of that and saying "It's a
> mystery but I'm not going to question it since it obviously works." But
> my more idealistic self is bothered that it isn't obvious to me why the
> ResultSet works despite its troubling aspects.
>
> Can you possibly shed some light on what is happening there?

Yes.

OK, I will actually do so.

'ResultSet' is not implemented in the standard Java API, but in the JDBC driver.

The instantiating class is always a subtype of 'ResultSet' specific to that
driver.

The details are hidden by the driver library. That's the WHOLE POINT of
interface-driven programming (a subset of type-driven programming)!

ALL you need to know is the interface! You want to AVOID the impulse "to
change ... to a real [sic] class or another sub-interface or whatever".

'ResultSet' works, like all interface-declared variables, because the variable
always points to an actual object which is an instance of a class.

VARIABLES ARE POINTERS!

The actual action happens in the object to which the variable points.

This is the heart and soul of polymorphism - you refer (point) to a supertype,
but the behavior is enacted by an instance of the subtype.

All the variable does is give you access to the behavior through the public
members of the variable's type. That access is always to the actual behavior
of the instance.

VARIABLES ARE POINTERS!

All your code cares about is that 'ResultSet' has certain behaviors. Those
are the behaviors promised by the type.

That way, when you change databases, say from (blecch!) MySQL to (ahhhh!)
PostgreSQL, you don't have to rewrite your code much. You still have a
'ResultSet' whose members are the members your code is already using; at run
time the JDBC driver returns a pointer to the actual instance to the
'ResultSet' variable.

VARIABLES ARE POINTERS!

--
Lew

Jeff Higgins

unread,
May 23, 2010, 4:58:40 PM5/23/10
to
On 5/23/2010 4:32 PM, Rhino wrote:

>
> Right now, I think I would benefit from the answer to a new mystery.

Please start a new thread.


>
> I do database stuff fairly frequently and mostly use my copy of DB2 as my
> database engine. Naturally, I use ResultSets for a lot of this work. I
> know that ResultSet is an interface, not a class, but it is rich in
> exactly the sorts of methods I need to grab the Strings, integers and
> whatnot in the database or to write them to the database. A short time
> ago, I was looking at the source for ResultSet and found that not one of
> the many methods in that interface are implemented; every single method
> seems to be abstract. I see in the JavaDoc that there are a number of
> "sub-interfaces" - I'm really not sure what a sub-interface is and how it
> is different from a interface and that it has a "super-interface" -
> again, I'm not sure what that is! - but the perplexing thing is that I am
> not explicitly using the super-interface or any of the sub-interfaces yet
> my code still works fine. That kind of thing disorients me; I wonder how
> that could possibly be working and why I don't need to change from
> ResultSet to a real class or another sub-interface or whatever. My
> pragmatic self is capable of just ignoring all of that and saying "It's a
> mystery but I'm not going to question it since it obviously works." But
> my more idealistic self is bothered that it isn't obvious to me why the
> ResultSet works despite its troubling aspects.
>
> Can you possibly shed some light on what is happening there?
>

Otherwise this goes on to troll alert.

Jeff Higgins

unread,
May 23, 2010, 6:41:06 PM5/23/10
to
Hal Vaughan?

Arne Vajhøj

unread,
May 23, 2010, 7:15:23 PM5/23/10
to
On 23-05-2010 16:32, Rhino wrote:
> I do database stuff fairly frequently and mostly use my copy of DB2 as my
> database engine. Naturally, I use ResultSets for a lot of this work. I
> know that ResultSet is an interface, not a class, but it is rich in
> exactly the sorts of methods I need to grab the Strings, integers and
> whatnot in the database or to write them to the database. A short time
> ago, I was looking at the source for ResultSet and found that not one of
> the many methods in that interface are implemented;

The number of methods is completely orthoginal to abstract base
class versus interface.

Interfaces never has any implementations so no surprise that ResultSet
does not have any.

Arne

Arne Vajhøj

unread,
May 23, 2010, 7:21:59 PM5/23/10
to

An interface never has any implementation so all methods are always
abstract - now and in the future.

An abstract class will usually have one or more abstract methods and one
or more non-abstract methods now or at least in the future, because
otherwise it could have been either a non-abstract class or an
interface.

Another practical difference is that classes can implement many
interfaces but can only extend one class (incl. abstract classes).

>> Variables have a type - that's what's important. When you use a
>> variable of type 'Foo', all you really care about is to use its
>> 'fooishBehavior()'.
>>
> I always tend to think of variables as things like
>
> String greeting = "Hello";
>
> from my COBOL days. But you're using variable where I might say instance,
> right?

In this case greeting is a variable that contains a reference
to an instance/object of class String.

> As in this case, where the variable myform is being instantiated:
>
> Form myForm = new Form();
>
> I'm pretty sure you mean the latter because 'myForm' in this case
> presumably has some number of behaviours (methods) to do this and that.
> Then again, by virtue of being a String, 'fred' has behaviours too, such
> as length() and substring(). Hmm, maybe this is a "distinction without a
> difference".

Exact same situation. Except that "Hello" is string literal that get a
bit special treatment.

> After all,
>
> String greeting = "Hello";
>
> is equivalent to:
>
> String greeting = new String("Hello");

Not quite.

The last form is wasting an extra object (unless is
somehow got optimized away).

Arne

Arne Vajhøj

unread,
May 23, 2010, 7:25:52 PM5/23/10
to

http://en.wikipedia.org/wiki/YAGNI

It is a paradigm about waiting to implement something
until you really need it because in many cases you waste
time developing sophisticated features that will never
be used.

Arne

Arne Vajhøj

unread,
May 23, 2010, 7:30:23 PM5/23/10
to
On 23-05-2010 14:53, Rhino wrote:
> Lew<no...@lewscanon.com> wrote in news:hta0s6$dmk$1...@news.albasani.net:
>> I strongly advise you, again!, to stick with SSCCEs until you stop
>> making that kind of mistake. That you have not learned your lesson
>> about posting uncompilable code is starting to make you look careless
>> and lazy.
>>
> Honestly, I think you're being just a little too rigid now.
>
> I was trying to get across the idea that, at first glance, Map<String,
> Locale> sorted Locales = new SortedMap<String, Locale>() might be
> something I would CONSIDER writing to address the suggestion that was
> made to me. I was trying to get across the idea that these statements all
> start to look alike and interchangeable at some point, at least to me. I
> know that this is not actually the case but it SEEMS like it sometimes.
> Fundamentally, I'm just expressing frustration with myself that it isn't
> more intuitive by now which of these statements is the one to use and
> which ones don't even make sense.
>
> I know (now) that the statement in question wouldn't actually compile or
> make sense and I didn't actually try to compile it anywhere. It was
> strictly a hypothetical and I truly think it is reasonable to toss out a
> hypothetical now and again even if it is only to dismiss it very quickly
> as the responders rightly did. I will continue to do that - very
> sparingly I expect - and do so at my own peril. Maybe some of you will
> disgusted with me for doing so and stop responding to me. If so, that's
> life. I'll do what penance is needed to get back into everyone's good
> graces or move on to some other discussion group if I have to.

The problem with pseudo code outlines is that there are
no well-defined syntax and semantics for it.

So you can not communicate efficiently with other, because
you may think X means one thing, but the readers may
think X means something else.

Java has a well-defined syntax and semantics that makes
it unambiguous for communication. And if there are any
doubt then the compiler and the JLS well help sort it out.

Posting pseudo-code that is very similar to Java is very
very bad, because that quickly changes the topic of
discussion from your real problem to the syntax errors.

Arne


Jeff Higgins

unread,
May 23, 2010, 7:35:00 PM5/23/10
to
On 5/23/2010 7:30 PM, Arne Vajh�j wrote:

> The problem with pseudo code outlines is that there are
> no well-defined syntax and semantics for it.
>
> So you can not communicate efficiently with other, because
> you may think X means one thing, but the readers may
> think X means something else.
>
> Java has a well-defined syntax and semantics that makes
> it unambiguous for communication. And if there are any
> doubt then the compiler and the JLS well help sort it out.
>
> Posting pseudo-code that is very similar to Java is very
> very bad, because that quickly changes the topic of
> discussion from your real problem to the syntax errors.
>

Thank you.

Lionel

unread,
May 28, 2010, 6:26:10 PM5/28/10
to
On 22/05/10 10:14, Arne Vajh�j wrote:

> On 21-05-2010 19:23, Rhino wrote:
>> Arne Vajh�j<ar...@vajhoej.dk> wrote in
> But no methods > 3 lines is not good either.


public class SomeContainer {
int attribute1;
int attribute2;
bool isAttribute3;

public SomeContainter() {
attribute1 = 0;
attribute2 = 0;
isAttribute3 = false;
}

public void setAttribute1(final int newValue) {
attribute1 = newValue;
}

public void setAttribute2(final int newValue) {
attribute2 = newValue;
}

public void setIsAttribute3(final bool newValue) {
isAttribute3 = newValue;
}

public int getAttribute1() {
return attribute1;
}

public int getAttribute2() {
return attribute2;
}

public int isAttribute3() {
return isAttribute3;
}
}

???

Arne Vajhøj

unread,
May 28, 2010, 8:34:31 PM5/28/10
to

Yes.

It is a very bad application. No logic at all. Due to no
main method, then i can not even be ran.

:-)

Arne


Lew

unread,
May 28, 2010, 11:16:53 PM5/28/10
to
Arne Vajhøj wrote in

>> But no methods > 3 lines is not good either.

Lionel wrote [a good example of Arne's point]:

> public class SomeContainer {
> int attribute1;
> int attribute2;
> bool isAttribute3;
>
> public SomeContainter() {
> attribute1 = 0;
> attribute2 = 0;
> isAttribute3 = false;
> }

You don't even need this constructor.

> public void setAttribute1(final int newValue) {
> attribute1 = newValue;
> }

Getters and setters model attributes, not behaviors. Arne's comment applied
to behaviors.

> public void setAttribute2(final int newValue) {
> attribute2 = newValue;
> }
>
> public void setIsAttribute3(final bool newValue) {
> isAttribute3 = newValue;
> }
>
> public int getAttribute1() {
> return attribute1;
> }
>
> public int getAttribute2() {
> return attribute2;
> }
>
> public int isAttribute3() {
> return isAttribute3;
> }
> }
>
> ???

Exactly, "???". What are you supposed to do with this class?

--
Lew

0 new messages