Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Hairy generics question

Reply
Thread Tools

Hairy generics question

 
 
sclaflin
Guest
Posts: n/a
 
      02-21-2012
I have a number of sets of matched parameterized classes: a bean, a
presenter, and a view.
The presenters and views have parallel inheritance hierarchies (where
T is the bean type, P the presenter type, and V is the view type):

public class CompA extends CompItem<AInfo, CompA, CompAView>
public class CompB extends CompItem<BInfo, CompB, CompBView>

public class CompAView extends CompItemView<AInfo, CompA, CompAView>
public class CompBView extends CompItemView<BInfo, CompB, CompBView>

public class CompItemView<T extends CompItemInfo,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P,
V>>
extends AbstractCompItemView<T, P, V>
implements CompItemViewInterface<T, P, V>

public abstract class CompItem<T extends CompItemInfo,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T,
P, V>>
extends AbstractCompItem<T, P, V>
implements CompWidget<T>

Many of the views are the same, so I wanted to just use the base view
class instead of creating a separate view class for each presenter.
So I tried:

public class CompA extends CompItem<AInfo, CompA, CompItemView>

But I get an error that says "The type CompItemView is not a valid
substitute for the bounded parameter <V extends
CompItemViewInterface<T,P,V>> of the type CompItem<T,P,V>.
Why can I use a class that extends CompItemView for the V type, and
not CompItemView itself?
 
Reply With Quote
 
 
 
 
Lew
Guest
Posts: n/a
 
      02-21-2012
On 02/21/2012 06:30 AM, sclaflin wrote:
> I have a number of sets of matched parameterized classes: a bean, a
> presenter, and a view.
> The presenters and views have parallel inheritance hierarchies (where
> T is the bean type, P the presenter type, and V is the view type):
>
> public class CompA extends CompItem<AInfo, CompA, CompAView>
> public class CompB extends CompItem<BInfo, CompB, CompBView>
>
> public class CompAView extends CompItemView<AInfo, CompA, CompAView>
> public class CompBView extends CompItemView<BInfo, CompB, CompBView>
>
> public class CompItemView<T extends CompItemInfo,
> P extends AbstractCompItem<T, P, V>,
> V extends CompItemViewInterface<T, P,
> V>>
> extends AbstractCompItemView<T, P, V>
> implements CompItemViewInterface<T, P, V>
>
> public abstract class CompItem<T extends CompItemInfo,
> P extends AbstractCompItem<T, P, V>,
> V extends CompItemViewInterface<T,
> P, V>>
> extends AbstractCompItem<T, P, V>
> implements CompWidget<T>
>
> Many of the views are the same, so I wanted to just use the base view
> class instead of creating a separate view class for each presenter.
> So I tried:
>
> public class CompA extends CompItem<AInfo, CompA, CompItemView>
>
> But I get an error that says "The type CompItemView is not a valid
> substitute for the bounded parameter<V extends
> CompItemViewInterface<T,P,V>> of the type CompItem<T,P,V>.
> Why can I use a class that extends CompItemView for the V type, and
> not CompItemView itself?


Your generics assertions have 'P' extend an 'AbstractCompItem' that depends on
'P'. This type of generics circularity has a place, but it's often the result
of confusion also. Which is it for you? Why does 'P' extend its own type?
(Similarly for 'V'.)

As for covariance, you need to study the generics tutorial
<http://docs.oracle.com/javase/tutorial/extra/generics/index.html>
and Angelika Langer's site.

The combination is likely what's killing you. Remember that 'Foo extends Bar'
does not imply (cannot imply) that 'Baz<Foo> extends Baz<Bar>'.

If you remove the circularity - if feasible, but please do explain why it's
there at all - and do your covariance correctly your problem should vanish. I
think perhaps you've overcomplicated your generics.

--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedi.../c/cf/Friz.jpg
 
Reply With Quote
 
 
 
 
Roedy Green
Guest
Posts: n/a
 
      02-21-2012
On Tue, 21 Feb 2012 06:30:51 -0800 (PST), sclaflin
<(E-Mail Removed)> wrote, quoted or indirectly quoted someone
who said :

>Why can I use a class that extends CompItemView for the V type, and
>not CompItemView itself?


Possibly because it thinks you are trying to implement multiple
abstract classes not Interfaces. Generics don't use the term
"extends" consistently which sows confusion. I did not follow your
details. I am just throwing that out.

--
Roedy Green Canadian Mind Products
http://mindprod.com
One of the most useful comments you can put in a program is
"If you change this, remember to change ?XXX? too".

 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      02-22-2012
On 2/21/12 6:30 AM, sclaflin wrote:
> I have a number of sets of matched parameterized classes: a bean, a
> presenter, and a view.
> The presenters and views have parallel inheritance hierarchies (where
> T is the bean type, P the presenter type, and V is the view type):
>
> public class CompA extends CompItem<AInfo, CompA, CompAView>
> public class CompB extends CompItem<BInfo, CompB, CompBView>
>
> public class CompAView extends CompItemView<AInfo, CompA, CompAView>
> public class CompBView extends CompItemView<BInfo, CompB, CompBView>
>
> public class CompItemView<T extends CompItemInfo,
> P extends AbstractCompItem<T, P, V>,
> V extends CompItemViewInterface<T, P,
> V>>
> extends AbstractCompItemView<T, P, V>
> implements CompItemViewInterface<T, P, V>
>
> public abstract class CompItem<T extends CompItemInfo,
> P extends AbstractCompItem<T, P, V>,
> V extends CompItemViewInterface<T,
> P, V>>
> extends AbstractCompItem<T, P, V>
> implements CompWidget<T>
>
> Many of the views are the same, so I wanted to just use the base view
> class instead of creating a separate view class for each presenter.
> So I tried:
>
> public class CompA extends CompItem<AInfo, CompA, CompItemView>
>
> But I get an error that says "The type CompItemView is not a valid
> substitute for the bounded parameter<V extends
> CompItemViewInterface<T,P,V>> of the type CompItem<T,P,V>.
> Why can I use a class that extends CompItemView for the V type, and
> not CompItemView itself?


I'll try to propose a way to fix your type declarations, but then I'll
make a better suggestion, please read through

I think what you'll need to do is have generic parameter to CompA:

public class CompA<View extends CompItemViewInterface<AInfo,
CompA<View>, View>> extends CompItem<AInfo, CompA<View>, View>

The better suggestion that I have for you is to try to find a better way
of handling this generic-type interdependency. I once wrote something
very similar, and it is a headache to maintain. Especially when I needed
to add in (I'm making up names to match your example) CompItemAccessor.
And then later CompItemValidator. And so on. I eventually ended up with
one class ContentTypeMetadata<X,Y,Z,A,B,C> which contained all the basic
information for each content type, and the class types didn't really
have to know much about each other.

Ask yourself, do all these objects really need to know the exact type of
all the other objects, or can they just know about some shared base
interface?


 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      02-22-2012
Daniel Pitts wrote:
> The better suggestion that I have for you is to try to find a better way of
> handling this generic-type interdependency. I once wrote something very
> similar, and it is a headache to maintain. Especially when I needed to add in
> (I'm making up names to match your example) CompItemAccessor. And then later
> CompItemValidator. And so on. I eventually ended up with one class
> ContentTypeMetadata<X,Y,Z,A,B,C> which contained all the basic information for
> each content type, and the class types didn't really have to know much about
> each other.
>
> Ask yourself, do all these objects really need to know the exact type of all
> the other objects, or can they just know about some shared base interface?


Or some bunch of non-generic interfaces?

And do they really all need to implement all these interfaces, or can they
compose elements that do?

"Favor composition over inheritance".
- Joshua Bloch, /Effective Java/

--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedi.../c/cf/Friz.jpg
 
Reply With Quote
 
Steven Simpson
Guest
Posts: n/a
 
      02-22-2012
On 22/02/12 02:04, Daniel Pitts wrote:
> I think what you'll need to do is have generic parameter to CompA:
>
> public class CompA<View extends CompItemViewInterface<AInfo,
> CompA<View>, View>> extends CompItem<AInfo, CompA<View>, View>


I think you then have to do the same for your AInfo, with corresponding
changes to CompA's declaration:

class CompA<View extends CompItemViewInterface<AInfo<View>,
CompA<View>, View>>
extends CompItem<AInfo<View>, CompA<View>, View> { }
class AInfo<View extends CompItemViewInterface<AInfo<View>,
CompA<View>, View>>
extends CompItemInfo<AInfo<View>, CompA<View>, View> { }



For the interested, here's an SSCCE, with CompC as the special case, and
CompA and CompB defined as before (and a few bits guessed):

interface CompWidget<T> { }

class CompItemInfo
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>> { }

interface CompItemViewInterface
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>> { }

abstract class AbstractCompItem
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>> { }

abstract class CompItem
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>>
extends AbstractCompItem<T, P, V>
implements CompWidget<T> { }

class CompItemView
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>>
extends AbstractCompItemView<T, P, V>
implements CompItemViewInterface<T, P, V> { }

abstract class AbstractCompItemView
<T extends CompItemInfo<T, P, V>,
P extends AbstractCompItem<T, P, V>,
V extends CompItemViewInterface<T, P, V>> { }



class CompA extends CompItem<AInfo, CompA, CompAView> { }

class AInfo extends CompItemInfo<AInfo, CompA, CompAView> { }

class CompAView implements CompItemViewInterface<AInfo, CompA, CompAView> { }



class CompB extends CompItem<BInfo, CompB, CompBView> { }

class BInfo extends CompItemInfo<BInfo, CompB, CompBView> { }

class CompBView implements CompItemViewInterface<BInfo, CompB, CompBView> { }



class CompC<View extends CompItemViewInterface<CInfo<View>,
CompC<View>, View>>
extends CompItem<CInfo<View>, CompC<View>, View> { }


class CInfo<View extends CompItemViewInterface<CInfo<View>,
CompC<View>, View>>
extends CompItemInfo<CInfo<View>, CompC<View>, View> { }





--
ss at comp dot lancs dot ac dot uk

 
Reply With Quote
 
sclaflin@webucator.com
Guest
Posts: n/a
 
      02-24-2012
Well, after writing a long response addressing the more structure-related comments, my submission got lost in the ether.

Suffice to say, I believe that the circularity is necessary at the deeper levels of my framework. My endpoint presenters act as widgets to the outside world, where I have indeed removed most of the types, except the bean type. But, any individual presenter is intimately tied to a view, since both need to invoke specific methods on the other. Some views need to know P, and presenters need to know V. In order to have abstract base views and presenters, the self-parametrization arose - this is a presenter for V, but only those V that support at least this P.

Unfortunately, when I tried to come up with a reduced set of declarations to post, I oversimplified and left out some of the nested parametrization. And, when I went to put those back in, I realized the issue. Once I lock in the base view, the V disappears.

So, the real issue was not with the class that I found the error in, which was trying to use CompItemView, but in CompItemView itself, when I left in the V parameter. It should be:

public class CompItemView<
T extends CompInfo,
P extends AbstractCompItem<T, P, CompItemView<T, P>>>
extends AbstractCompItemView<T, P, CompItemView<T, P>>
implements CompItemViewInterface<T, P, CompItemView<T, P>>

after removing the V from the CompItemView parametrization.
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      02-24-2012
On 02/24/2012 11:12 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Well, after writing a long response addressing the more structure-related comments, my submission got lost in the ether.
>
> Suffice to say, I believe that the circularity is necessary at the deeper levels of my framework. My endpoint presenters act as widgets to the outside world, where I have indeed removed most of the types, except the bean type. But, any individual presenter is intimately tied to a view, since both need to invoke specific methods on the other. Some views need to know P, and presenters need to know V. In order to have abstract base views and presenters, the self-parametrization arose - this is a presenter for V, but only those V that support at least this P.


Perhaps the circularity is necessary, but I've worked with my fellows on a few
hairy generics issues where circularity seemed necessary, and it never was.
Each time it turned out that an acyclic type graph did the trick, and better
than the initial circular approach.

Of course since you can't share any of the relevant details we have no way of
helping you see if there is an acyclic approach. Still, I cannot accept your
simple declaration that there isn't. The odds are just too strongly against it.

> Unfortunately, when I tried to come up with a reduced set of declarations to post, I oversimplified and left out some of the nested parametrization. And, when I went to put those back in, I realized the issue. Once I lock in the base view, the V disappears.
>
> So, the real issue was not with the class that I found the error in, which was trying to use CompItemView, but in CompItemView itself, when I left in the V parameter. It should be:
>
> public class CompItemView<
> T extends CompInfo,
> P extends AbstractCompItem<T, P, CompItemView<T, P>>>
> extends AbstractCompItemView<T, P, CompItemView<T, P>>
> implements CompItemViewInterface<T, P, CompItemView<T, P>>
>
> after removing the V from the CompItemView parametrization.


That's a step in circularity reduction. How is it necessary when your own
experience shows that its removal helped? I'm confused.

--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedi.../c/cf/Friz.jpg
 
Reply With Quote
 
sclaflin@webucator.com
Guest
Posts: n/a
 
      02-24-2012
On Friday, February 24, 2012 3:03:56 PM UTC-5, Lew wrote:
> On 02/24/2012 11:12 AM, sclaflin wrote:


> Perhaps the circularity is necessary, but I've worked with my fellows on a few
> hairy generics issues where circularity seemed necessary, and it never was.
> Each time it turned out that an acyclic type graph did the trick, and better
> than the initial circular approach.
>
> Of course since you can't share any of the relevant details we have no way of
> helping you see if there is an acyclic approach. Still, I cannot accept your
> simple declaration that there isn't. The odds are just too strongly against it.
>



Lew,

You could well be right. I based my structure on a framework that had Presenter<V> and View, but then the view didn't know how to talk to the presenter. So, they add in ReverseView<P> separately. I was trying to combine them both, and with those dual sorts of situations I've always ended up with circularity.

You guessed that I've got proprietary code that I can't share, and I'm supposed to be spending time on that, not general-purpose things. But, if I can come up with a minimal but complete example, I'll post it.

> > Unfortunately, when I tried to come up with a reduced set of declarations to post, I oversimplified and left out some of the nested parametrization. And, when I went to put those back in, I realized the issue. Once I lock in the base view, the V disappears.
> >
> > So, the real issue was not with the class that I found the error in, which was trying to use CompItemView, but in CompItemView itself, when I leftin the V parameter. It should be:
> >
> > public class CompItemView<
> > T extends CompInfo,
> > P extends AbstractCompItem<T, P, CompItemView<T, P>>>
> > extends AbstractCompItemView<T, P, CompItemView<T, P>>
> > implements CompItemViewInterface<T, P, CompItemView<T, P>>
> >
> > after removing the V from the CompItemView parametrization.

>
> That's a step in circularity reduction. How is it necessary when your own
> experience shows that its removal helped? I'm confused.
>

I have minimal circularity in the classes that finally get instantiated -- it's the middle levels of concrete and abstract base classes that have the hairy generic stuff. The intent of the particular code I posted was to reuse one view class for a number of presenters where the view could render the bean from its toString method. But I've been operating under the belief that I would still need to have those circular mid-level classes available to extend matched views and presenters for unique cases.
 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      02-24-2012
On 2/24/12 2:07 PM, (E-Mail Removed) wrote:
> On Friday, February 24, 2012 3:03:56 PM UTC-5, Lew wrote:
>> On 02/24/2012 11:12 AM, sclaflin wrote:

>
>> Perhaps the circularity is necessary, but I've worked with my fellows on a few
>> hairy generics issues where circularity seemed necessary, and it never was.
>> Each time it turned out that an acyclic type graph did the trick, and better
>> than the initial circular approach.
>>
>> Of course since you can't share any of the relevant details we have no way of
>> helping you see if there is an acyclic approach. Still, I cannot accept your
>> simple declaration that there isn't. The odds are just too strongly against it.
>>

>
>
> Lew,
>
> You could well be right. I based my structure on a framework that had Presenter<V> and View, but then the view didn't know how to talk to the presenter. So, they add in ReverseView<P> separately. I was trying to combine them both, and with those dual sorts of situations I've always ended up with circularity.
>
> You guessed that I've got proprietary code that I can't share, and I'm supposed to be spending time on that, not general-purpose things. But, if I can come up with a minimal but complete example, I'll post it.


In what way is a Presenter different from a "controller". View's should
never know about Controllers, only about models. Controllers know about
specific views and specific models. Models know about generic
listeners, if you need to have an active view (non web-app stuff).
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
generics depending on generics Soul VHDL 0 02-02-2009 09:14 AM
Hairy brainstorm castironpi@gmail.com Python 2 02-19-2008 09:32 PM
Using std::set::insert(hint p, e) ("hairy") desktop C++ 6 06-13-2007 09:21 AM
question on generics, constants in vhdl geoffrey wall VHDL 1 10-01-2005 08:48 PM
Can't convert a generics list of objects into a generics list ofinterfaces Juergen Berchtel Java 1 05-20-2005 02:07 PM



Advertisments