MVP + UiBinder, thoughts?

608 views
Skip to first unread message

Dalla

unread,
Nov 30, 2009, 4:39:12 PM11/30/09
to Google Web Toolkit
I´ve been working on some small projects using GWT 1.6.4 and 1.7.1.
I know alot of people tried their best to pick up on Ray Ryans "GWT
Best practice" from Google IO 2009,
where using MVP was one of the main guidelines.

I recently started looking at GWT RC1 and the new UiBinder.
Using the UiBinder it seems like the only way to handle events from
the components defined
are to handle them with the @UiHandler annotation inside the view
class.
This seems to move things away from MVP, at least the way I learned,
or did I miss something here?

What are your thoughts on this?

Thomas Broyer

unread,
Nov 30, 2009, 5:31:17 PM11/30/09
to Google Web Toolkit
You can very well just have your components have a ui:field attribute,
with the corresponding @UiField-annotated field on your View class,
and then return the component from a getter method (defined on the
Display interface implemented by the View); then on your presenter,
call the addXXXHandler to add your event handler.
That's what we're doing for 2 months now (as soon as 2.0 MS1 were
available) and it works very well.

> What are your thoughts on this?

There was a discussion some weeks ago about optimization of handlers
and implementing them all in one inner-class instead of using multiple
anonymous classes (one at each addXXXHandler call point generally),
and some one (Ray Ryan?) responded that UiBinder's @UiHandler could do
this automatically (in the future), or could even come with something
even more optimized, so that if you really wanted to optimize your
code you'd rather use @UiHandler than creating such an inner class by
hand.
Now, that effectively doesn't fit very well with Ray's presentation at
I/O, but it still puts layout management out of your view (java code;
pun intended) and pushed in to the ui.xml file; so, the ui.xml would
somehow be the view and the java class that calls it via UiBinder the
presenter. But this effectively defeats unit testing using mocks such
as with EasyMock.

mariyan nenchev

unread,
Nov 30, 2009, 5:32:18 PM11/30/09
to google-we...@googlegroups.com
I started to use MVP architecture today, it seems really good. I am little afraid if this event bus can handle the "pressure" if there are too many events for handling, but since this is in the core gwt architecture i hope it will.
As for the uibinder i do not use it. I think it will be useful for really big projects where there are teams of developers and designers, you know. But for small and medium projects without big designers job, it makes no sense to use it. I assume it fits right on the google guys projects :).
Regards.

mariyan nenchev

unread,
Nov 30, 2009, 5:34:29 PM11/30/09
to google-we...@googlegroups.com
Btw does someone know open source projects with more complex UI, than hupa project with this architecture, or some non trivial examples?

Dalla

unread,
Dec 1, 2009, 12:36:06 AM12/1/09
to Google Web Toolkit
OK, so if I understand you correctly, you´re not using the @UiHandler
annotation at all?
Sounds like a good approach which won´t affect the MVP pattern as we
know it at all.

mariyan nenchev

unread,
Dec 1, 2009, 3:48:22 AM12/1/09
to google-we...@googlegroups.com
Yes, it has nothing to do with MVP. If your team is small and none of them are designers i don't see a reason to use uibinder.

Dalla

unread,
Dec 1, 2009, 4:14:24 AM12/1/09
to Google Web Toolkit
It´s pretty much a one man team (me), so maybe I won´t benefit very
much from using the UiBinder then...

Thomas Broyer

unread,
Dec 1, 2009, 5:42:21 AM12/1/09
to Google Web Toolkit


On Dec 1, 6:36 am, Dalla <dalla_man...@hotmail.com> wrote:
> OK, so if I understand you correctly, you´re not using the @UiHandler
> annotation at all?
> Sounds like a good approach which won´t affect the MVP pattern as we
> know it at all.

Right; we only use @UiField and @UiField(provided=true).

Well, there are some cases where we could use @UiHandler actually (in
a view, we turn some ClickEvents into SelectionEvents), but the guy
who worked on these view wasn't aware of @UiHandler, and I completely
forgot about it too, so I didn't catch when reviewing his code
;-)

Thomas Broyer

unread,
Dec 1, 2009, 5:54:12 AM12/1/09
to Google Web Toolkit

On Dec 1, 9:48 am, mariyan nenchev <nenchev.mari...@gmail.com> wrote:
> Yes, it has nothing to do with MVP. If your team is small and none of them
> are designers i don't see a reason to use uibinder.

We're a small team (4 full-time devs, only 2 of them working on client
code; none of us is designer) and we do use UiBinder for nearly 2
months (2.0 MS1) and find it very useful, and productivity gain!

For best performances (we're targeting IE6, as it's our client's
"company standard", unfortunately), we started doing some screens
using HTMLPanel. UiBinder binder makes the code:
- easier to read (Eclipse is not good at formatting String
concatenations, much better at formatting XML)
- faster to write and less error-prone (now that we have auto-
completion and validation for GWT widgets in the Eclipse plugin)
- easier to understand, because the Java code for the view is simpler

Compared to our "legacy" app (UiBinder is used in a new app, to work
side-by-side with a year-and-half-old GWT app still using widgets the
GWT-1.7-way, without MVP, DI, etc.), the code is much "cleaner" with
UiBinder.
My only fear is that we hit the 31-stylesheets limit of IE, which
might come quite quickly when using CssResource (both "explicitly",
and "automagically" through UiBinder)

uwfrog

unread,
Dec 1, 2009, 11:12:55 AM12/1/09
to Google Web Toolkit
I found MVP works great with UiBinder. MVP pattern abstracts logic
from widget so that most of logic(i.e., calculation, rpc calls) can be
mocked and tested in plain junit test cases separately from those have
to be run in GWTTestCases. What's left in the V part are now layout
code in the widget which usually are lots of messy code with panels,
styling, and positioning. UiBinder cleans up the mess with html.

Dalla

unread,
Dec 1, 2009, 12:33:51 PM12/1/09
to Google Web Toolkit
Lots of good thoughts. Cleaning up the code inside the view sounds
really nice,
so I guess I´ll be sticking with UiBinder after all :-)

Does anyone know any good resources for testing examples using GWT?
I would be interested in examples using plain JUnit aswell as
GWTTestCase.

fmk11

unread,
Dec 14, 2009, 5:25:14 PM12/14/09
to Google Web Toolkit
Very interesting thread;

One question .. how does using @UiHandler in the View code maintain
MVP? I would like to stick to @UiHandler annotation, but it seems to
me that testing will get hurt. My current thinking is going with
something similar to what Thomas described above.

Jonas Huckestein

unread,
Dec 15, 2009, 3:41:57 AM12/15/09
to Google Web Toolkit

> One question .. how does using @UiHandler in the View code maintain
> MVP? I would like to stick to @UiHandler annotation, but it seems to
> me that testing will get hurt. My current thinking is going with
> something similar to what Thomas described above.

I recall having read on the gin list a couple of months ago, that it
might be useful to reverse the dependency of the view and presenter in
MVP. You could inject a "presenter" class into the class containing
the @UiHandler annotations and from the view call methods on the
presenter. I have to figure this out in the next couple of weeks since
I am not yet sure about a lot of things. For instance, does the
presenter need to know about the view class or can it be agnostic by
requiring all data to be passed to its methods? This would remove the
need to have hundreds of *.Display interfaces and would make testing
easier since it would not require that much mocking.

And here is a slightly different question: Does anyone have experience
with how fast the HTMLUnit tests can run? My feeling is, that the plan
for GWT might be to move away from hacks like MVP alltogether. I think
the annotation-style of UI bindings is also well suited to build
automated tests on mock UIs in the future and my feeling is that
sticking close to all of UiBinder's features might not be a bad
idea ...

In case anyone is interested, I could try to pretty up the framework
code we currently use for a large GWT 2 application and perhaps post
it here or soething (I will have to check that with my team though ;))

Cheers, Jonas

bcottam

unread,
Dec 28, 2009, 2:25:12 AM12/28/09
to Google Web Toolkit
just following up on this. I've just started using the UiBinder and
love it. I really like how clean it makes my UI code. However, I was
kind of struggling with the @UiHandler annotation and how it fit in
with the whole MVP paradigm as well. Your suggestion Jonas is great
(i.e. reversing the MVP dependency linkage) however, I wonder if a
more decoupled approach may be appropriate. For instance, I really
like the idea that I can make a UI interface that defines properties
(getName() setName() etc) rather than HTML DOM elements
(getNameTextField() etc.) so I don't want to be putting my UI class in
charge of migrating data from my ui inputs to my presenter. So, I
thought, perhaps some really simple event driven api might work:

public class MyPresenter implements SaveCancelHandler {
public interface Display {
public String getName();
public void setName(String name);
....
}

public void saveClicked(ClickEvent event) {
....
}
public void cancelClicked(ClickEvent event) {
....
}

}

public class MyPanel extends Composite implements MyPresenter.Display
{
@UiField TextBox nameBox;
@UiField Button saveButton;
@UiField Button cancelButton;

private SaveCancelHandler handler;

public void setSaveCancelHandler(SaveCancelHandler handler) {
this.handler = handler;
}

public void setName(String name) {
nameBox.setText(name);
}
public String getName() {
return nameBox.getText();
}

@UiHandler("saveButton")
public void saveClicked(ClickEvent event) {
handler.saveClicked(event);
}

@UiHandler()
public void cancelClicked(ClickEvent event) {
handler.cancelClicked(event);
}

}

// this could be a nested class, but this one seems really common:
public interface SaveCancelHandler {
public void saveClicked(ClickEvent event);
public void cancelClicked(ClickEvent event);
}

of course, this could be done with some more elegant events/handler
definitions etc and perhaps a nice HandlerManager so multiple Handlers
could be added to your display. This eliminates the anonymous class
definitions and leaves both your UI and Presenter with a rather clean
api. I'm playing around with this pattern now, so I don't know if
there is some pitfall waiting to bite me, but so far it's working well
and I like it *lots* better than this stuff:

getDisplay().addSaveHandler( new ClickHandler() {
public void onClick(ClickEvent event) {
saveClicked(event);
}
});

On Dec 15, 1:41 am, Jonas Huckestein <jonas.huckest...@me.com> wrote:
> > One question .. how does using @UiHandlerin the View code maintain
> > MVP? I would like to stick to @UiHandlerannotation, but it seems to


> > me that testing will get hurt. My current thinking is going with
> > something similar to what Thomas described above.
>
> I recall having read on the gin list a couple of months ago, that it
> might be useful to reverse the dependency of the view andpresenterin
> MVP. You could inject a "presenter" class into the class containing

> the @UiHandlerannotations and from the view call methods on thepresenter. I have to figure this out in the next couple of weeks since
> I am not yet sure about a lot of things. For instance, does thepresenterneed to know about the view class or can it be agnostic by

bcottam

unread,
Dec 28, 2009, 2:46:09 AM12/28/09
to Google Web Toolkit
oh, not sure why I didn't think of this earlier, the EventBus is a
perfect way to handle this (well, it's pretty good anyway :) )
so instead of:

public void setSaveCancelHandler(SaveCancelHandler handler) {
this.handler = handler;
}

you could just do:
SaveCancelEvent event = new SaveCancelEvent();
eventBus.fireEvent(event);

of course this assumes you are fine with making event APIs for your
displays.

and you don't have to have your Display keeping track of instances of
listeners on it. That, and anyone can listen to your events,
although, usually I would think only your Presenter would be
listening.
cheers
-bryce

FKereki

unread,
Dec 28, 2009, 9:43:12 AM12/28/09
to Google Web Toolkit
I use @UiHandler to define a handler that will call a callback, which
the Presenter injects into the View.

Thus, the View still fits the "humble object" definition, and the
Presenter is responsible for whatever gets done.

bryce cottam

unread,
Dec 28, 2009, 12:18:49 PM12/28/09
to google-we...@googlegroups.com
I'm not sure I'm picturing what you mean. Like I said, I've only been
playing with UiBinder for a few days. My goal is that I really want
to avoid doing boiler plate anonymous ClickHandler/SelectHandler etc.
etc. So, what you are doing sounds a lot like what I am suggesting
but perhaps I don't fully understand your approach. Would you mind
posting a few code snippets? I'm eager to establish some best
practices.

thanks!
-bryce

> --
>
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>
>
>

FKereki

unread,
Dec 29, 2009, 8:47:00 AM12/29/09
to Google Web Toolkit
Here goes... I'm doing a simple form that allows you to browse all
cities whose names start with a given string.

The ui.xml file contains a textbox, a couple of buttons, and a grid;
the relevant lines are:

<g:HTMLPanel>
<h1>CitiesUpdater</h1>
Start of City Name:
<g:TextBox u:field="cityNameStart"/>
<g:Button u:field="getCitiesButton" text="Get Cities"/>
<g:Button u:field="updateCitiesButton" text="Update Cities"/>
<hr />
<g:FlexTable u:field="cg"/>
</g:HTMLPanel>

The View includes:

@UiTemplate("CitiesUpdaterView.ui.xml")
interface Binder extends UiBinder<HTMLPanel, CitiesUpdaterView> {}
private static final Binder binder = GWT.create(Binder.class);

@UiField TextBox cityNameStart;
@UiField Button getCitiesButton;
@UiField Button updateCitiesButton;
@UiField FlexTable cg;

SimpleCallback<Object> onGetCitiesClickCallback;
SimpleCallback<Object> onUpdateCitiesClickCallback;
SimpleCallback<Object> onCityNameStartChangeCallback;

@Override
public void setOnCityNameStartChangeCallback(SimpleCallback<Object>
acb) {
onCityNameStartChangeCallback = acb;
}

@Override
public void setOnGetCitiesClickCallback(SimpleCallback<Object> acb)
{
onGetCitiesClickCallback = acb;
}

@Override
public void setOnUpdateCitiesClickCallback(SimpleCallback<Object>
acb) {
onUpdateCitiesClickCallback = acb;
}

@UiHandler("cityNameStart")
void uiOnChange(ChangeEvent event) {
onCityNameStartChangeCallback.onSuccess(null);
}

@UiHandler("getCitiesButton")
void uiOnGetClick(ClickEvent event) {
onGetCitiesClickCallback.onSuccess(null);
}

@UiHandler("updateCitiesButton")
void uiOnUpdateClick(ClickEvent event) {
onUpdateCitiesClickCallback.onSuccess(null);
}

The Presenter includes:

public CitiesUpdaterPresenter(
final String params, final CitiesUpdaterDisplay
citiesUpdaterDisplay,
final Environment environment) {

// ...

getDisplay().setOnGetCitiesClickCallback(new SimpleCallback<Object>
() {
// ...code to run, when the Get Cities button is clicked
});

getDisplay().setOnUpdateCitiesClickCallback(new
SimpleCallback<Object>() {
// ...code to run when the Update button is clicked
});

getDisplay().setOnCityNameStartChangeCallback(new
SimpleCallback<Object>() {
//...code to run whenever the CityNameStart field changes
}

So...

* the Presenter is injected with the Display (View) to use
* the Presenter injects three callbacks into the View
* the View uses @UiHandler to define three handlers
* the handlers just call the callbacks that were set by the Presenter

Note that SimpleCallback is an extension of AsyncCallback.

I hope this is clearer; I deleted as much code as possible, to make
the example simpler. Please ask again if you have any doubts or
questions.

Best regards,
F.Kereki

bryce cottam

unread,
Dec 29, 2009, 4:37:39 PM12/29/09
to google-we...@googlegroups.com
thanks for the code,
I'm actually trying to avoid the anonymous class code:

getDisplay().setOnCityNameStartChangeCallback(new
SimpleCallback<Object>() {
//...code to run whenever the CityNameStart field changes
}

and rather have simple member methods be invoked like:

public void onCityNameStartFieldChange() {
....
}

that gets directly invoked by the View.

I'm kinda getting sick of writing anonymous classes.
The approach you are suggesting is quite similar to just making
anonymous ClickHanders or ValueChangeHandler instances.
I'd much rather define higher level events.

So, if I had a view that had a few fields:


@UiField Button saveButton;
@UiField Button cancelButton;

@UiField Button addEmailButton;

I'd like to have some relevant api defined for ui events that is
business logic agnostic, so something like this:

public interface BeanHandler {
public void saveClicked();
public void cancelClicked();
public void emailAdded();
}

etc. perhaps these methods could have parameters, like some event
that had contextual data (like what view class fired the event), but
basically this boils down to this:

@UiHandler("saveButton")
public void onSaveClicked(ClickEvent event) {
beanHandler.saveClicked();
}

@UiHandler("cancelButton")
public void onCancelClicked(ClickEvent event) {
beanHandler.cancelClicked();
}

@UiHandler("addEmailButton")
public void onAddEmailClicked(ClickEvent event) {
beanHandler.emailAdded();
}


and of course, beanHandler is just some instance of an interface that
gets injected via a setter or something.

then your presenter turns into this:

public class BeanPresenter implments BeanHandler {

..... business logic methods...
// BeanHandler methods:

public void saveClicked() {
someService.save(myBean);
}
public void cancelClicked() {
getDisplay().reset();
}
public void emailAdded() {
String email = getDisplay().getEmailValue();
myBean.addEmail(email);
}
}

this accomplishes the same things you itemize above, it's just that
you don't have to deal with boiler plate anonymous classes that
(usually) invoke the same kinds of methods I just defined, usually you
have something like this:

ClickHandler handler = new ClickHandler() {
public void onClick(ClickEvent event) {
saveClicked();
}
}

public void saveClicked() {
....
}

I'm leaning towards any approach that cuts out the boiler plate code
above. In essence, your approach and what I have in mind do the same
thing, I just want to avoid the anonymous classes :)

thanks!
-bryce

FKereki

unread,
Dec 29, 2009, 6:53:41 PM12/29/09
to Google Web Toolkit
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?

bryce cottam

unread,
Dec 29, 2009, 7:55:01 PM12/29/09
to google-we...@googlegroups.com
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

István Szoboszlai

unread,
Jan 29, 2010, 4:29:39 AM1/29/10
to google-we...@googlegroups.com
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
--
Best Regards
- István Szoboszlai
istvan.s...@inepex.com | +36 30 432 8533 | inepex.com

Matt Read

unread,
Jan 29, 2010, 5:42:03 AM1/29/10
to google-we...@googlegroups.com
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 <mrs...@gmail.com>

bryce cottam

unread,
Jan 29, 2010, 3:37:28 PM1/29/10
to google-we...@googlegroups.com
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

ross

unread,
Feb 21, 2010, 2:33:12 PM2/21/10
to Google Web Toolkit
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)

> > 2010/1/29 István Szoboszlai <mrsz...@gmail.com>


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

> >> istvan.szobosz...@inepex.com | +36 30 432 8533 | inepex.com

ross

unread,
Feb 21, 2010, 2:38:20 PM2/21/10
to Google Web Toolkit
oops I hit 'send' by accident while copy/pasting the View code, here's
the correct snippet:

---------------------------------------------
View
---------------------------------------------
public class MyView extends Composite implements MyPresenter.Display {

@UiField
Label backLabel;

MyPresenter.DisplayHandlers handlers;

@UiHandler("backLabel")
void handleBackClick(ClickEvent e) {
handlers.onBackLabelClicked();
}

@Override
public void setDisplayHandlers(MyPresenter.DisplayHandlers handlers)
{
this.handlers = handlers;
}

}
---------------------------------------------

bryce cottam

unread,
Feb 21, 2010, 10:00:39 PM2/21/10
to google-we...@googlegroups.com
Ross:
not sure if I put it in the code I posted (and frankly I'm too lazy to
check right now)
but since your view extends Composite, you can do handy things like:

addHandler(...);
fireEvent(myEvent);

so, if your DisplayHandlers interface extends Presenter, and you have
a simple Event that extends GwtEvent, then you have a really handy way
of tracking listeners (i.e. you don't have to track them, the
GwtFramework does). that, and you can avoid any nested classes that
have inline implementations.... just a thought.

thanks for the post!!

best regards,
-bryce

PhilBeaudoin

unread,
Mar 4, 2010, 8:30:40 PM3/4/10
to Google Web Toolkit
Just a quick thought... If you wanted to make the Presenter-View
relationship bidirectional without having to inject it manually,
couldn't you have GIN inject a Provider<MyPresenter.DisplayHandlers>
into the view? Then you just bind MyPresenter.DisplayHandlers to
MyPresenter.

On Feb 21, 11:33 am, ross <ross.m.sm...@googlemail.com> wrote:
> 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 onUiBinder+MVPpatterns but maybe we'll have to wait for I/O

> > as far as your usingUiBinder+MVPwithout 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 <mr...@spotd.co.uk> wrote:
> > > Hi, could you possible re-cap on what problem this approach solves? I'm

> > > usingUIBinderwithmvp-presenter without inverting the dependencies in this

bryce cottam

unread,
Mar 5, 2010, 3:16:16 PM3/5/10
to google-we...@googlegroups.com
indeed, that's the direction I'm going with it. I wasn't using GIN at
first, (since everything I was doing was proof of concept) but now
that I'm "really" coding it, GIN comes in quite handy for this.

Fabio Kaminski

unread,
Mar 5, 2010, 4:13:44 PM3/5/10
to google-we...@googlegroups.com
the way i see, when UiBinder arrives it has made the Presenter/Display design behind it..
particularly i find a little painful to write that kind of weird coding..

in that way UiBinder was a blessing, cause, in my point of view the ui.xml file its similar to display as the view tier..
and leave the widget .java  file to write only the event handling logic similar to presenter tier in that example..

and the best of it.. with less code and confusion, with a new xml artefact that could be handled by a designer focused on it if you wish so, that does'nt need any java knowlodge  or to open the source and compile every time you need to change the view tier..

bryce cottam

unread,
Mar 5, 2010, 4:24:37 PM3/5/10
to google-we...@googlegroups.com
well, as Ray Ryans talk indicates, the UiBinder and the MVP patterns
work quite well together (i.e. the UiBinder doesn't leave the MVP
behind).
Here's the thing with making the view's .java file contain business
logic: it's business logic in your view. The ui.xml is simply for
layout, it's has no concept of control statements (if/else/for etc.)
so *some* java code needs to back it. That java code that backs the
view should really be view-centric, not business logic centric.

The first time I played with UiBinder I was quite tempted to put raw
event handling in the view's .java file, however it felt wrong
(especially after watching Ray Ryans GWT Best Practices talk), so that
drove me to having the view dispatch events rather than control the
UI's business logic. For instance: sometimes you need to pull things
from the backend server based on an event from the user (choosing
something from a drop down, clicking on a checkbox etc.) it just feels
wrong to have a class that extends Composite handle that kind of
traffic. Hence the decision to have a Presenter manage that
communication.

History has shown when you have a clear, distinct separation of
concerns between your UI and your business logic your code is more
stable, note that this isn't a clear line drawn between the UI event
handling and the UI layout. :)

I guess it all boils down to preference, but I do happen to have
experience working on projects where business logic is embedded in
display level classes and it simply isn't scalable (i.e. you can't
swap out the display easily, and you can't ever re-use the business
logic code unless you load your whole UI framework).

just a thought,
-bryce

Eduardo Nunes

unread,
Mar 5, 2010, 7:57:13 PM3/5/10
to google-we...@googlegroups.com
The UiBinder just help you to create the UI (view) of the MVP. I wouldn't use the annotations available to bind handlers. UiBinder just help me to create the view of components or even pages in way that a designer can change some part of the HTML for example without modifying the behavior of the application due to the Display interface.
Eduardo S. Nunes
http://enunes.org
Reply all
Reply to author
Forward
0 new messages