Design Question re Comparable

R

Rhino

I need a sanity check on a design I am considering.

I am trying to design a simple class called Range, which subclasses Object.
I want Range to store a two-element array of Objects that are both of the
exact same class. However, I only want to store Objects if it is possible to
determine which of the two is the lower value. Integers have intrinsic order
so two Integers can obviously can be compared to see which is lower, however
two JPanels do not have intrinsic order (aside from creation sequence which
I consider irrelevant for my purposes) so they have no intrinsic order.
Therefore, I have no problem in creating a Range of Integers but don't want
to create a Range of JPanels.

It seems to me that my best approach is to see if the Objects that are
passed to my Range constructor implement the Comparable interface. If they
do, I can compare the two Objects in the constructor and determine which is
the lower value.

I can use the getInterfaces() method in Class to determine the interfaces
implemented by the incoming Objects and then use the compareTo() method
defined for that class to find out which is lower, then store it as a class
variable called 'lowValue'; the other Object gets stored in 'highValue'.
Then I can write a between() method to determine if a third value is within
the Range defined by the two Objects in the Range.

Is this design basically sound?

Followup question: If this design is sound, how do I compare the actual
values of the Objects? In my constructor, I know that they belong to the
same class and that the class implements Comparable but how do I actually
see which is lower? I have to cast them from Object to their actual class
and then do compareTo() right? If so, how do I cast them from Object to
their actual class? I know the following does NOT compile because the
firstObject.getClass() is not an actual class name, just something that
resolves to a class name, which isn't good enough for the compiler:

if ( ((firstObject.getClass()) firstObject).compareTo(
((secondObject.getClass()) secondObject)) > 0) {
}

So how do I compare the two values to see which is lower? I assume there is
some standard idiom that will let me do this but I don't know what it is.

--
Rhino
---
rhino1 AT sympatico DOT ca
"There are two ways of constructing a software design. One way is to make it
so simple that there are obviously no deficiencies. And the other way is to
make it so complicated that there are no obvious deficiencies." - C.A.R.
Hoare
 
E

Eric Sosman

Rhino said:
I need a sanity check on a design I am considering.

I am trying to design a simple class called Range, which subclasses Object.
I want Range to store a two-element array of Objects that are both of the
exact same class. However, I only want to store Objects if it is possible to
determine which of the two is the lower value. Integers have intrinsic order
so two Integers can obviously can be compared to see which is lower, however
two JPanels do not have intrinsic order (aside from creation sequence which
I consider irrelevant for my purposes) so they have no intrinsic order.
Therefore, I have no problem in creating a Range of Integers but don't want
to create a Range of JPanels.

It seems to me that my best approach is to see if the Objects that are
passed to my Range constructor implement the Comparable interface. If they
do, I can compare the two Objects in the constructor and determine which is
the lower value.

I can use the getInterfaces() method in Class to determine the interfaces
implemented by the incoming Objects and then use the compareTo() method
defined for that class to find out which is lower, then store it as a class
variable called 'lowValue'; the other Object gets stored in 'highValue'.
Then I can write a between() method to determine if a third value is within
the Range defined by the two Objects in the Range.

Is this design basically sound?

The design is sound, but you're working far too hard.
Just define the Range constructor to take two Comparable
objects:

public Range(Comparable x, Comparable y)

Now, this isn't *quite* enough, because two classes that
implement Comparable might not be comparable to each other:
if `x' is a String and `y' is an Integer, both implement
Comparable but the attempt to use either's compareTo()
method on the other will fail. However, since you're
planning to use compareTo() anyhow to discover how `x'
and `y' map to `lowValue' and `highValue', any such problem
will be detected immediately: the compareTo() method will
throw an exception and the constructor will exit.

(Advanced and optional topic: See also Comparator for
a way to compare non-Comparable objects.)
Followup question: If this design is sound, how do I compare the actual
values of the Objects? In my constructor, I know that they belong to the
same class and that the class implements Comparable but how do I actually
see which is lower? I have to cast them from Object to their actual class
and then do compareTo() right?

No cast is needed; just use compareTo(). That's what
polymorphism is all about.

Forgive me for saying so, but several of your questions
have a strong "beginner flavor" about them, which suggests
that they probably belong in comp.lang.java.help rather than
here. It also suggests that you need to drag out your Java
textbook again and re-read it; something didn't "take" the
first time around.
 
R

Rhino

Eric Sosman said:
The design is sound, but you're working far too hard.
Just define the Range constructor to take two Comparable
objects:

public Range(Comparable x, Comparable y)
D'OH!

I had a feeling there was an easier way than what I was doing... ;-)
Now, this isn't *quite* enough, because two classes that
implement Comparable might not be comparable to each other:
if `x' is a String and `y' is an Integer, both implement
Comparable but the attempt to use either's compareTo()
method on the other will fail. However, since you're
planning to use compareTo() anyhow to discover how `x'
and `y' map to `lowValue' and `highValue', any such problem
will be detected immediately: the compareTo() method will
throw an exception and the constructor will exit.
Yes, I had that worry in the back of my mind; thanks for explaining how to
handle it.
(Advanced and optional topic: See also Comparator for
a way to compare non-Comparable objects.)
Okay....


No cast is needed; just use compareTo(). That's what
polymorphism is all about.
Again, I assumed there was an easier way than what I was doing. It felt
kludgey to cast the objects before comparing them but I couldn't compare to
straight Objects directly so I wasn't sure how to proceed. It never occurred
to me to pass two Comparables to the constructor; I thought you could only
pass classes to a constructor, not interfaces.
Forgive me for saying so, but several of your questions
have a strong "beginner flavor" about them, which suggests
that they probably belong in comp.lang.java.help rather than
here. It also suggests that you need to drag out your Java
textbook again and re-read it; something didn't "take" the
first time around.
The main textbook I used was 1001 Java Programmer's Tips, written back in
the Java 1.0 days; it's not what most people would call strong on giving OO
design concepts ;-)

That's why I've enjoyed this discussion; I've already gotten some ideas for
good OO and Java design books. I really need to fill in a lot of my
conceptual gaps ;-)

Rhino
 
C

Chris Uppal

Eric said:
The design is sound, but you're working far too hard.
Just define the Range constructor to take two Comparable
objects:

public Range(Comparable x, Comparable y)

Now, this isn't *quite* enough, because two classes that
implement Comparable might not be comparable to each other:

If Rhino wants an additional sanity check (I wouln't bother myself, but...)
then doing

x.compareTo(y);
y.compareTo(x);

in the constuctor would catch most cases where the end-points didn't agree on
how to compare things.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,481
Members
44,900
Latest member
Nell636132

Latest Threads

Top