Hey all,
I have been wrestling with this design pattern the past week or so on
my application architecture. I am eagerly awaiting to hear Google's
stance on UiBinder + MVP patterns but maybe we'll have to wait for I/O
to find that out :)
In the meantime I really appreciated this thread and I've gone with
something very much along the lines of what Bryce mentioned with
having the 'Execute' interface in the Presenter. Having the 'Execute'
interface defined in the View seemed too circular for me (and also the
javac) :)
Here's my code:
---------------------------------------------
Presenter
---------------------------------------------
public class MyPresenter implements Presenter {
public interface DisplayHandlers {
void onBackLabelClicked();
}
public interface Display {
void setDisplayHandlers(DisplayHandlers handlers);
Widget asWidget();
}
public MyPresenter(..., HandlerManager eventBus,
Display display) {
this.eventBus = eventBus;
this.display = display;
}
@Override
public Widget bind() {
display.setDisplayHandlers(new DisplayHandlers() {
@Override
public void onBackLabelClicked() {
// fire an event on the bus or whatever else you may fancy
}
});
return display.asWidget();
}
}
---------------------------------------------
View
---------------------------------------------
public class ErrorView extends Composite implements
ErrorPresenter.Display {
@UiField
Label backLabel;
ErrorPresenter.DisplayHandlers handlers;
}
---------------------------------------------
hope this helps someone (only relevant code is shown)
On Jan 29, 3:37 pm, bryce cottam <[email protected]> wrote:
> Yes, I am using this pattern and liking it quite a bit right now. I
> feel it cleans up a lot of boiler-plate code.
> Here is a sample application that demonstrates some of the design
> patterns I'm using (including the Command Pattern for RPC calls):
>
> http://www.resmarksystems.com/code/GwtSample.zip
>
> It's pretty basic, and some things could be improved (like the use of
> GIN/Guice and some more reflection based RPC dispatching on the
> server), but I didn't go to great lengths to include that because the
> main thing I wanted to demonstrate in this code was the use of the MVC
> tweaks brought up in this thread.
>
> I want to emphasize that it was thrown together for a friend in order
> to demonstrate concepts and not as a tutorial walk through, it
> includes stuff like rpc based login (which I don't suggest using).
> Anyhow, I hope it helps demonstrate how I'm dispatching events.
>
> as far as your using UiBinder + MVP without any issues: I wouldn't say
> your "missing" anything per se', it's just that I wanted something
> cleaner than what I was seeing around the forums. I don't like
> returning HasText/HasClickHandler type interfaces from my view to my
> presenter 'cause I think my display can be smarter than that without
> embedding any business logic in it. I like making calls like
> display.getName() rather than display.getNameBox().getText(). When I
> do things that way, it makes it really easy to swap out my display
> instances with simple beans and I don't have to much with any testing
> frameworks like easymock or anything. I've found it to be helpful.
>
> cheers,
> -bryce
>
>
>
> On Fri, Jan 29, 2010 at 3:42 AM, Matt Read <[email protected]> wrote:
> > Hi, could you possible re-cap on what problem this approach solves? I'm
> > using UIBinder with mvp-presenter without inverting the dependencies in this
> > way without any problems so I'm wondering what I'm missing.
> > Thanks,
> > Matt.
>
> > 2010/1/29 István Szoboszlai <[email protected]>
>
> >> Hello Bryce,
>
> >> Are you using the approach you were describing in any project now with
> >> success? If so it would be very appreciated if you could write some
> >> sentences about your experiences.
> >> I thing I like what you proposed, and I also think it is not a big
> >> drawback that you have to inject the presenters 'execute' interface int he
> >> view by hand.
>
> >> So I think I will give a chance to this approach.
>
> >> I'll write if I have any conclusion (good, or bad).
>
> >> Best - Istvan
>
> >> On Wed, Dec 30, 2009 at 1:55 AM, bryce cottam <[email protected]> wrote:
>
> >>> very similar, but I think I either wanted to keep the Execute
> >>> interface on the Presenter (since the View is already dependent on a
> >>> nested interface from the Presenter) or having it on a top level
> >>> package. Come to think of it I think I tried to define the Execute
> >>> interface inside the Presenter and the compiler didn't like that, so I
> >>> wound up just making it a top level api Interface. I think this is
> >>> more decoupled than the interface being nested in the View
> >>> implementation, (since the Presenter is only dealing with interfaces
> >>> defined either in it's self, or in a top level package)
>
> >>> You are correct on the constructor injection though, you wouldn't be
> >>> able to inject both via constructor arguments, however, in the
> >>> Presenter constructor you could simply inject it's self into a setter
> >>> on the Display:
>
> >>> public MyPresenter(MyDisplay display) {
> >>> display.setExecute(this);
> >>> }
>
> >>> I'm used to Spring-style injection, which usually leverages some kind
> >>> of setter post-construction anyhow. You could even have some other
> >>> class implement the Executer api that just had a reference to the
> >>> Presenter instance, but that's a few levels of indirection for
> >>> delegating method calls :)
>
> >>> I guess it's a small trade off for me to self-inject in my constructor
> >>> rather than having Guice inject me if I can reduce boiler plate code.
>
> >>> I'm glad to hear you were at least considering my approach, it's nice
> >>> to know i'm not way off in left field.
>
> >>> -bryce
>
> >>> On Tue, Dec 29, 2009 at 4:53 PM, FKereki <[email protected]> wrote:
> >>> > I also gave a thought to your method, but in the end opted out... but
> >>> > I guess it's where you are heading.
>
> >>> > In the same way that the View implements Display, an interface defined
> >>> > in the Presenter class, Presenter could implement Execute, an
> >>> > interface defined in the View class.
>
> >>> > The View should have a method allowing injection of the Execute
> >>> > object; the Presenter would this "self injection" in its constructor.
>
> >>> > Then, whenever any event happened, the View handler would do getExecute
> >>> > ( ).someMethod( ).
>
> >>> > You would do away with all anonymous classes, and each class (View,
> >>> > Presenter) would implement an interface defined in the other class.
>
> >>> > The symmetry breaks down a bit because you cannot inject each object
> >>> > in the other through their constructors (obviously!)
>
> >>> > Is this along the lines you were thinking?
>
> >>> > --
>
> >>> > You received this message because you are subscribed to the Google
> >>> > Groups "Google Web Toolkit" group.
> >>> > To post to this group, send email to
> >>> > [email protected].
> >>> > To unsubscribe from this group, send email to
> >>> > [email protected].
> >>> > For more options, visit this group at
> >>> >http://groups.google.com/group/google-web-toolkit?hl=en.
>
> >>> --
>
> >>> You received this message because you are subscribed to the Google Groups
> >>> "Google Web Toolkit" group.
> >>> To post to this group, send email to [email protected].
> >>> To unsubscribe from this group, send email to
> >>> [email protected].
> >>> For more options, visit this group at
> >>>http://groups.google.com/group/google-web-toolkit?hl=en.
>
> >> --
> >> Best Regards
> >> - István Szoboszlai
> >> [email protected] | +36 30 432 8533 | inepex.com
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Google Web Toolkit" group.
> >> To post to this group, send email to [email protected].
> >> To unsubscribe from this group, send email to
> >> [email protected].
> >> For more options, visit this group at
> >>http://groups.google.com/group/google-web-toolkit?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Google Web Toolkit" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > For more options, visit this group at
> >http://groups.google.com/group/google-web-toolkit?hl=en.
--
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.