Advice using activities/places in MVP with some self-contained widgets

119 views
Skip to first unread message

Shaun Tarves

unread,
May 14, 2012, 3:48:14 PM5/14/12
to google-we...@googlegroups.com
I have an application utilizing A&P with an MVP set-up. There are some situations where I want to create some self-contained widgets (think, a small alert window that needs to fire and event or a box that might want to pull some data from a server). They aren't whole views and don't occupy entire display regions, but I want to maintain the MVP approach.

I've seen a few approaches that include specifying a callback interface in the widget that your presenters (the one driving the view that holds the widget) would implement, but that would mean writing the same code multiple times if you use the widget in more than one view.

I'm curious what people are doing when faced with this situation.

Thomas Broyer

unread,
May 15, 2012, 7:26:43 AM5/15/12
to google-we...@googlegroups.com
If they're self-contained, why would your presenter need to do anything special with them? Can't they simply be implementation details of your views?

As far as MVP is concerned, your self-contained widget could use MVP itself, it does not mean it has to be exposed and/or, if it is, the view should belong to the view of the containing component, and its presenter to the presenter of the containing component.
As an example, CellList, CellTable, et al. use MVP internally, but they don't expose it; it's an implementation detail that allows fast (non-GWTTestCase) unit-testing of the algorithms.

Shaun Tarves

unread,
May 15, 2012, 7:58:48 AM5/15/12
to google-we...@googlegroups.com
Sorry for not being clearer - self-contained wasn't the correct description. Modular is more what I meant; widgets in the sense that they could be used in multiple views, but still have the ability to interact with the rest of the app (fire events mostly). If they're widgets as used in uiBinder templates, how to I control the construction of them to include an event bus. Should I make the event bus static, declare a UiConstructor, or use injection?

Some of the examples (mobilewebapp) use a container and pass a "presenter" that implements IsWidget into it (for example the piechartpresenter), but others declare the actual widget in the uibinder files (expenses).

I'm mostly looking for a design pattern that others have found helpful with actual implementation (where/how to declare/construct) of MVP widgets. 

Thomas Broyer

unread,
May 15, 2012, 8:31:51 AM5/15/12
to google-we...@googlegroups.com


On Tuesday, May 15, 2012 1:58:48 PM UTC+2, Shaun Tarves wrote:
Sorry for not being clearer - self-contained wasn't the correct description. Modular is more what I meant; widgets in the sense that they could be used in multiple views, but still have the ability to interact with the rest of the app (fire events mostly). If they're widgets as used in uiBinder templates, how to I control the construction of them to include an event bus. Should I make the event bus static, declare a UiConstructor, or use injection?

Don't make the bus static!

You can use @UiFactory, @UiConstructor if you wish, or @UiField(provided=true).

In some very specific cases (because we had a lot of those widgets –a SuggestBox that needed a RequestFactory in our case– and a lot of views, and didn't want to add too much boilerplate in each view), we added a static field into the widget and used GIN's requestStaticInjection (ideally, you'd rather inject a Provider<> and call its get() from your constructor, to mimic dependency-injection).
This is only a workaround for the fact UiBinder isn't really GIN-friendly; it should IMO be explicitly documented in your code as being a workaround, and not a rule to follow ! (rather an exception to the rule).

I'm mostly looking for a design pattern that others have found helpful with actual implementation (where/how to declare/construct) of MVP widgets.

See http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html for an example of a presenter asking its view for a sub-view (and then attaching a sub-presenter to that sub-view). 

Yaniv Tal

unread,
May 15, 2012, 12:22:02 PM5/15/12
to Google Web Toolkit
I think your original hunch was correct. I like using a presenter or
"delegate" pattern. Choose an activity to control your widget. If your
widget is part of a view, that view should have a corresponding
activity and that should be the thing that controls your widget and
fires events on its behalf. Since your widget is the one that has
special needs, it should define what it needs. In the widget class
define an interface

public interface MyWidgetDelegate {
public void doMyThing();
}

Add a method to your widget class:
public void setDelegate(MyWidgetDelegate delegate) {
this.delegate = delegate;
}

Now your activity implements MyWidgetDelegate and the activity is
responsible for calling setDelegate(this);

Now whenever your widget needs it can call delegate.doMyThing() which
the activity implements and can be responsible for interacting with
the eventbus or doing any other smart thing.

I use this pattern all over the place and I think it's the cleanest
way to deal with this problem.

Thomas Broyer

unread,
May 17, 2012, 6:12:01 AM5/17/12
to google-we...@googlegroups.com
If all (or most) activities implement the interface the same, then you can cut duplicated code by having them *provide* the MyWidgetDelegate implementation to the view, so that you can have a single concrete class used everywhere. And in case an activity needs to do something special / different from the others, then it could still implement the interface and provide itself as the implementation to the view.
As for "providing the MyWidgetDelegate to the view", you can either add a getter to the presenter/activity (called by the view) or add a setter to the view (called by the presenter/activity). I prefer always pushing things to the other side, so I'd go with the setter, but YMMV.
Reply all
Reply to author
Forward
0 new messages