Hairy generics question

S

sclaflin

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?
 
L

Lew

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

Roedy Green

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

Daniel Pitts

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?
 
L

Lew

Daniel said:
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/
 
S

Steven Simpson

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> { }
 
S

sclaflin

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

Lew

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

sclaflin

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

Daniel Pitts

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

sclaflin

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

In my preferred concept of MVP, a view doesn't work directly with the model, which is why I suffixed my T type with Info. It's possible for the view to not know about the presenter, and a lot of MVP is done that way. But thatrequires the view to fire events that the presenter then registers to handle.

My problem with that approach is twofold:

1. It burdens a global event bus with lots of events that were only meant to be one source to one handler. Especially in my app, where most of my views would fire events like editRequested or deleteRequested (most of these widgets are display-only, the edits are done via a popup). So, the global event manager is going to have to hold a list of handlers for each event forall these views, and then iterate through the appropriate list each time to find the handler that matches the event source. While intellectually pleasing from a maximum decoupling perspective, it's not very efficient.

2. It exposes what ought to private publicly, that being the event registration methods. The view shouldn't be visible to anything but its presenter,but public void addEditRequestedHandler could be called from anywhere thathas a reference to the view. Granted, that reference shouldn't be held anywhere but in the presenter, but I could see someone that perceives MVP differently passing the reference outside the presenter.
 
A

Arved Sandstrom

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

For what it's worth, Daniel, JSF is arguably [1] MVP
(Model-View-Presenter) and not MVC (Model-View-Controller). There have
been many attempts to characterize JSF as MVC, and that's what most
folks think JSF is, but a body has to jump through some hoops in order
to define what the V and the C are in JSF in order to make that label
stick. MVP on the other hand is a much better description.

Struts is an MVC framework, JSF is MVP. Many folks (including Sun back
in the day) would have it that JSF is more of an MVC 2 framework using
front controllers, but IMHO it's really MVP. Using the duck test...

I myself don't lose much sleep over whether or not something is actually
classic MVC, new-model MVC, MVP or MVVM, or other named permutations
thereof. As Martin Fowler puts it, Separated Presentation is the the
notion we got from classic MVC, and all of the later variants give us
that. Provided that you're observing the proper separations and using
good OOP, why get religious? Not to knock MVVM, but just as an example
I've read through some threads about tiny little nuances of what is, and
isn't, MVVM, and I wonder why the posters don't go out there and get
some real work done instead of engaging in hairsplitting. :)

I'm laying this stuff out there simply to indicate that despite all the
terminology, much of it redundant and confusing and artificial, that MVC
and MVP are usefully different and real architectures, and that
Presenter is definitely not Controller.

AHS

1. A number of people have argued this point. :)
 
D

Daniel Pitts

I'm laying this stuff out there simply to indicate that despite all the
terminology, much of it redundant and confusing and artificial, that MVC
and MVP are usefully different and real architectures, and that
Presenter is definitely not Controller.

I guess I had never heard of MVP, and just assumed the OP was recreating
MVC without clearly understanding the concept. This apparently was
hubris on my part, and I humbly apologize for that.

I'm going to do a web search to learn more about MVP architecture later
today, but I want to know what it means to people in this group as well,
X-Posting to clj.gui, since it seems relevant.

So, fellow Java engineers and Pragmatic Programmers, how would you
compare and contrast MVC vs MVP? Are there design/clarity benefits to
one over the other? That does "Presenter" mean to you?

Thanks,
Daniel.
 
L

Lew

I guess I had never heard of MVP, and just assumed the OP was recreating MVC
without clearly understanding the concept. This apparently was hubris on my
part, and I humbly apologize for that.

I'm going to do a web search to learn more about MVP architecture later today,
but I want to know what it means to people in this group as well, X-Posting to
clj.gui, since it seems relevant.

So, fellow Java engineers and Pragmatic Programmers, how would you compare and
contrast MVC vs MVP? Are there design/clarity benefits to one over the other?
That does "Presenter" mean to you?

Only what I find on the Web:
<http://en.wikipedia.org/wiki/Model–view–presenter>

According to the fully authoritative and always-correct Wikipedia, it's a
particular variant of MVC, much as the front-controller pattern is a
particular variant of MVC.

Apropos of which, someone somewhere around these newsgroups complained that
MVC was bad for them because it centralized the controller. That's only the
one flavor of MVC that does that - it's not an essential feature of MVC that
there be only one controller.
 
A

Arne Vajhøj

Only what I find on the Web:
<http://en.wikipedia.org/wiki/Model–view–presenter>

According to the fully authoritative and always-correct Wikipedia, it's
a particular variant of MVC,

It do say:
Model–view–presenter (MVP) is a derivative of the
model–view–controller (MVC) software pattern

But I would more call it a brother or cousin than a son.
much as the front-controller pattern is a
particular variant of MVC.

Apropos of which, someone somewhere around these newsgroups complained
that MVC was bad for them because it centralized the controller. That's
only the one flavor of MVC that does that - it's not an essential
feature of MVC that there be only one controller.

I don't even think it is that common. Struts 1 is probably the most
widely used true MVC framework out there and it has multiple actions
(and actions are controller not model!).

Arne
 
S

sclaflin

My app is a GWT app, and Google is promoting their variant of MVP as a goodarchitecture for GWT apps. For those not familiar with GWT, it compiles client Java code to JavaScript for use in a browser in a web app.

In GWT, the view should be something for which a mock can be injected for unit testing, where the mock can be implemented with pure Java code, so thatthe testing doesn't have to be done using Javascript or a browser (the initialization of the test case when an actual browser is involved takes much longer). To accomplish this without jumping through a lot of hoops, the view needs to be pretty "dumb". There's a good presentation of this at http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html
 
D

Daniel Pitts

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

For what it's worth, Daniel, JSF is arguably [1] MVP
(Model-View-Presenter) and not MVC (Model-View-Controller). There have
been many attempts to characterize JSF as MVC, and that's what most
folks think JSF is, but a body has to jump through some hoops in order
to define what the V and the C are in JSF in order to make that label
stick. MVP on the other hand is a much better description.
I've just read the original Taligent, Inc. PDF on what MVP is, and it
looks like its little more than a clarification of MVC, with some new
concepts pulled out. Things that were inferred in the "controller" are
now their own concepts.

In that case, my original advice still stands. View shouldn't know
about the Presenter, only about the Model, and event listeners. The
Model shouldn't know about the View or Presenter, only about observers,
and the Presenter is basically knows about everything.

As such, you can't easily have a Generic Presenter. Also, as such, you
needn't have the view have any information about the "type" of the
Presenter. The View also only needs the interface type of the Model, not
the specific type. The Model needs only to know only interface types as
well.

This allows you to completely remove the circular type dependencies,
which is one of the main benefits of MVC and MVP architectures in the
first place.
 
D

Daniel Pitts

On 2/24/12 2:07 PM, (e-mail address removed) wrote:
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).

For what it's worth, Daniel, JSF is arguably [1] MVP
(Model-View-Presenter) and not MVC (Model-View-Controller). There have
been many attempts to characterize JSF as MVC, and that's what most
folks think JSF is, but a body has to jump through some hoops in order
to define what the V and the C are in JSF in order to make that label
stick. MVP on the other hand is a much better description.
I've just read the original Taligent, Inc. PDF on what MVP is, and it
looks like its little more than a clarification of MVC, with some new
concepts pulled out. Things that were inferred in the "controller" are
now their own concepts.

In that case, my original advice still stands. View shouldn't know about
the Presenter, only about the Model, and event listeners. The Model
shouldn't know about the View or Presenter, only about observers, and
the Presenter is basically knows about everything.

As such, you can't easily have a Generic Presenter. Also, as such, you
needn't have the view have any information about the "type" of the
Presenter. The View also only needs the interface type of the Model, not
the specific type. The Model needs only to know only interface types as
well.

This allows you to completely remove the circular type dependencies,
which is one of the main benefits of MVC and MVP architectures in the
first place.
And to further back up my point, a reference:
 
L

Lew

Daniel said:
I've just read the original Taligent, Inc. PDF on what MVP is, and it looks
like its little more than a clarification of MVC, with some new concepts
pulled out. Things that were inferred in the "controller" are now their own
concepts.

Other references make a similar point, or conversely take great pains to
distinguish MVP (most valuable player) from MVC. Such care would be
unnecessary were the concepts actually so different.

"MVC" is a pretty loose term, which accounts for some of the controversy. In
large terms it means no more than "model-view-controller" and the principle of
separation of concerns imply. Really, the taxonomy dispute is by the wayside.
Personally, I recognize "MVC" as the species, like the first "lupus" in "canis
lupus lupus", and subspecies, like the second "lupus". Then "MVP" would be
another subspecies, like the "familiaris" in "canis lupus familiaris".

Life - Domain - Kingdom - Phylum -
Engineering - Computer - Software - Programming -

Class - Order - Family - Genus - Species - Sub
Architecture - Patterns - Modular - Acyclic - MVC - MVC
Architecture - Patterns - Modular - Acyclic - MVC - MVP

So MVC is the wolf, and MVP the dog.

That's just an offhand metaphor, a "Lewnnaeus" classification, if you will.
Perhaps it will help some of you.
In that case, my original advice still stands. View shouldn't know about the
Presenter, only about the Model, and event listeners. The Model shouldn't know
about the View or Presenter, only about observers, and the Presenter is
basically knows about everything.

As such, you can't easily have a Generic Presenter. Also, as such, you needn't
have the view have any information about the "type" of the Presenter. The View
also only needs the interface type of the Model, not the specific type. The
Model needs only to know only interface types as well.

This allows you to completely remove the circular type dependencies, which is
one of the main benefits of MVC and MVP architectures in the first place.

The pattern itself is acyclic, which accounts for how it accomplishes that:
"knows about":
P |- V |- M
|- M

This translates almost directly into type dependencies.

I don't usually make the Controller (or Presenter) generic. It works just fine
with non-generic 'Screen' (a View artifact) and 'Handler' types sorta like
this (pseudocode):

public class Controller
{
static enum Outcome {SUCCESS, FAILURE, ERROR};
private final Map<Screen, Handler> handlers = loadHandlerMap();
private final Map<Screen, Map<Outcome, Screen>> navigations
= loadNavigations();

public void process(Request request, Response response)
{
Screen screen = request.getScreen();
Handler handler = handlers.get(screen);
Outcome outcome = handler.handle(request, response);
Screen next = navigations.get(screen).get(outcome);
forward(next, request, response);
}
// etc.
}

Of course, this is just one way to do the pattern. It's what I use for Web
apps if I'm hand-rolling, and not dissimilar to how Struts does things;
however, I've been doing this since before Struts was available.
 
A

Arved Sandstrom

On 2/24/12 2:07 PM, (e-mail address removed) wrote:
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).

For what it's worth, Daniel, JSF is arguably [1] MVP
(Model-View-Presenter) and not MVC (Model-View-Controller). There have
been many attempts to characterize JSF as MVC, and that's what most
folks think JSF is, but a body has to jump through some hoops in order
to define what the V and the C are in JSF in order to make that label
stick. MVP on the other hand is a much better description.
I've just read the original Taligent, Inc. PDF on what MVP is, and it
looks like its little more than a clarification of MVC, with some new
concepts pulled out. Things that were inferred in the "controller" are
now their own concepts.

In that case, my original advice still stands. View shouldn't know
about the Presenter, only about the Model, and event listeners. The
Model shouldn't know about the View or Presenter, only about observers,
and the Presenter is basically knows about everything.

As such, you can't easily have a Generic Presenter. Also, as such, you
needn't have the view have any information about the "type" of the
Presenter. The View also only needs the interface type of the Model, not
the specific type. The Model needs only to know only interface types as
well.

This allows you to completely remove the circular type dependencies,
which is one of the main benefits of MVC and MVP architectures in the
first place.

Let me put it this way. Like I said above, if you're going to make a
distinction between MVC and MVP at all (and a lot of people don't,
because they've never heard of MVP, or they choose not to worry about
the distinction), then MVP describes JSF better than MVC does.

If you choose to think of JSF as MVC - let's say because you aren't
interested in breaking out MVP as a derivative of MVC - then that's fine
too. I have no problem with that, it's what I actually do myself,
because most folks haven't heard of MVP anyway so why confuse them? I
would like it though if people who "knowledgeably" classify JSF as being
MVC could identify what the Controller is in JSF: I've run across more
people than not who either think it's the FacesServlet or just don't know.

AHS
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top