Command Pattern, MVP, EventBus

706 views
Skip to first unread message

Kwhit

unread,
Jul 11, 2009, 2:41:06 AM7/11/09
to Google Web Toolkit
Just throwing up an idea here to see how many bullet holes it comes
down with.

I'm playing around with the command pattern which is a hot topic at
the moment and wondered why it shouldn't be merged with the EventBus?
The command pattern proposed by RR has to add a response object - the
original doesn't (I don't have a GoF copy to hand), using and event
bus would remove the requirement for it.

Using the example presented by RR.

1/ User clicks on 'save' to save the edited phone number

2/ Presenter creates an RpcCommandEvent{<save>, <new phone number>}
and fires it to the eventBus

3/ RpcPipe, listening for RpcCommandEvent events, ships them off the
to the server

--- Server side ---

4/ RpcPipeService receives the event and invokes a specialized handler

5/ The handler verifies (for the sake of the example but I would
normally do this client side) the new phone number, finds it OK and
updates the storage

6/ Handler returns new phone number for contact ID x

7/ RpcPipeService ships (returns) the response on across the pipe

--- Back on the client side ---

8/ RpcPipe fires the RPC return value as an event on the bus

9/ Listeners to ContactInfoUpdated events update the phone number

I, in my ignorance, find the above a net gain

* +ve: One pipe fits all, no need to update the mechanics of the RPC
* +ve, -ve: The event designer has to know that the event should be
shipped over the pipe
* +ve: The statefulness of the RPC mechanism (every request has a
response) fades away
* +ve: In fact the Pipe itself could disappear with a bus on the
server (see below) - end to end unit testing

In my event driven fever I would also like to have an event bus on the
server so that the handlers could register themselves for events but I
not worried too much about that yet.

OK fire away!


Adligo

unread,
Jul 11, 2009, 6:11:43 PM7/11/09
to Google Web Toolkit
Hi Kwhit,

I believe that this is what I have been calling the Controller
(Event Bus, passing Events (Command Objects)). Perhaps why I have
had some difficulty working with others (GWT) MVC frameworks of late.

So I have a Event Object (Command) with a Object value field
http://cvs.adligo.org/viewvc/adi/src/org/adligo/i/adi/client/EventDelegator.java?view=markup
http://cvs.adligo.org/viewvc/gwt_util/src/org/adligo/gwt/util/client/UserEventController.java?view=markup
http://cvs.adligo.org/viewvc/gwt_util/src/org/adligo/gwt/util/client/BaseController.java?view=markup
http://cvs.adligo.org/viewvc/gwt_util/src/org/adligo/gwt/util/client/SystemEventController.java?view=markup

View->Sends Event->UserEventController->Delegates to some code
View<-Recieves Data<-SystemEventController<-Delegated Code responds
So the 'Event Bus' is made up of two major sections
tword control code
from control code

Each section may have multiple parts so things can be added (removed)
from the bus. I wrote this before the 2009 Google IO MVP
presentation, and was trying to combine newer MVC frameworks (Spring,
Struts) with older GoF smalltalk C++ ideas about fat clients (lexi).

So I made some generalizations (more casting since Object is often my
reference type), and my View and Presentation code is generally
packaged into a class name ending with Panel (AddressPanel for
instance).

In your example I would have the SavePhoneNumberButton as the Source
of the event and the NewPhoneNumber as the value. The event would get
to some rpc code, onSuceess would change the NewPhoneNumber value in
the Event object and pass it back to the View.

So to sum up, I think the Command Pattern with the Event Bus is the
way to go, and works well for me! I called this a MVC framework.

Cheers,
Scott

David Peterson

unread,
Jul 13, 2009, 9:31:00 PM7/13/09
to Google Web Toolkit
There's certainly nothing to stop you, and you could even just add
your own RPC Event and have a listener trigger the server-side call.
In fact, in my own implementation of Ray's example (http://
code.google.com/p/gwt-dispatch), the Action and Response are both
interfaces, so you could just have the base class be a GwtEvent
subclass.

The main complication I guess is the server side. I haven't tested to
see if you can just use a custom EventHandler server-side without
changes, but I'm guessing it would work fine.

David

Alejandro D. Garin

unread,
Jul 14, 2009, 12:43:29 PM7/14/09
to Google-We...@googlegroups.com
Hi,

I wrote an implementation (first try) based on the Command Pattern and EventBus described in the Ray Google IO Talk. (what I understand from the slides).
The working example is trivial but the code uses an event bus (using gwt HandleManager) and the command pattern for the RPC Service.

Comments are welcome, I would like to know if the implementation is good.

Thanks,

Alejandro D. Garin

unread,
Jul 14, 2009, 12:46:10 PM7/14/09
to Google-We...@googlegroups.com

David Peterson

unread,
Jul 15, 2009, 3:36:37 PM7/15/09
to Google Web Toolkit
Thinking further, I think it's better to separate the EventBus from
the Command system somewhat. The reason being that generally, events
are used to update on changes that have already happened, or are about
to happen. They don't trigger the actual event itself.

For example, you have a 'CreateUserEvent'. This is sent out and three
listeners pick it up. There is no way to control the order the
handlers are sent the event, so one might actually create the user,
and the others expect it to already be created. You'll have issues at
that point. Also, what happens if the creation fails? Should the event
keep propogating, or stop?

It's also more difficult to provide feedback to the original creator
if there were problems. Yes, it could send out another event over the
bus, but then you end up with custom 'error' events all over the
place...

Anyway, I've ended up implementing them separately. In fact, they are
completely decoupled from each other - so much so that I've got two
separate projects for them:

Command Pattern API:
http://code.google.com/p/gwt-dispatch

Presenter Pattern API:
http://code.google.com/p/gwt-presenter

The latter is 'fresher', meaning it's subject to change. gwt-dispatch
is pretty solid now - I'll be releasing 1.0 shortly. Have a look and
let me know what you think.

David

Alejandro D. Garin

unread,
Jul 15, 2009, 10:54:33 PM7/15/09
to Google-We...@googlegroups.com
Hi David,

On Wed, Jul 15, 2009 at 4:36 PM, David Peterson <da...@randombits.org> wrote:

Thinking further, I think it's better to separate the EventBus from
the Command system somewhat. The reason being that generally, events
are used to update on changes that have already happened, or are about
to happen. They don't trigger the actual event itself.

My understanding is that some Events need to be fired from the RPC Service (see slide #46 from Ray talk). In my example I have events like EmployeeAddEvent fired only when the RPC call is returned sucessfull, then all views listening this event are notified.
 
For example, you have a 'CreateUserEvent'. This is sent out and three
listeners pick it up. There is no way to control the order the
handlers are sent the event, so one might actually create the user,
and the others expect it to already be created. You'll have issues at
that point. Also, what happens if the creation fails? Should the event
keep propogating, or stop?

I didn't understand your point. I have four listeners and each listener is receiving a diferent Event, then one listener receive employee aditions, other listener employee deletes, etc.
(lines 114 to 166)

It's also more difficult to provide feedback to the original creator
if there were problems. Yes, it could send out another event over the
bus, but then you end up with custom 'error' events all over the
place...

If an error ocurr with the RPC request then the application wide failure handling (see slide #24) will notify the user about the error. There is no need for new events.
 

Anyway, I've ended up implementing them separately. In fact, they are
completely decoupled from each other - so much so that I've got two
separate projects for them:

Command Pattern API:
Presenter Pattern API:
http://code.google.com/p/gwt-presenter

Thanks about your comments, I will check your project and send my feedback.
Regards,

David Peterson

unread,
Jul 16, 2009, 5:30:04 AM7/16/09
to Google Web Toolkit
Hi Alejandro,

Firstly, you can absolutely do it using the same EventBus. I just
don't think it's that great a fit, personally. But if what you have
works, use it :)

> > Thinking further, I think it's better to separate the EventBus from
> > the Command system somewhat. The reason being that generally, events
> > are used to update on changes that have already happened, or are about
> > to happen. They don't trigger the actual event itself.
>
> My understanding is that some Events need to be fired from the RPC Service
> (see slide #46 from Ray talk). In my example I have events like
> EmployeeAddEvent fired only when the RPC call is returned sucessfull, then
> all views listening this event are notified.

Yes. The example in the presentation essentially had a custom
implementation of AsyncCallback for each Action. Each one would have a
custom response, which may or may not trigger a unique event into the
EventBus. So far, exactly what my current system does - it just
provides the 'Dispatch' RPC service for you, without hooking into the
EventBus system.

However, my app has it's own subclass of the dispatcher which _does_
trigger an event, if the Response supports it. But, the original call,
and the actual action execution is not done via events - just a
notification after the Command has executed successfully (or
otherwise).

> > It's also more difficult to provide feedback to the original creator
> > if there were problems. Yes, it could send out another event over the
> > bus, but then you end up with custom 'error' events all over the
> > place...
>
> If an error ocurr with the RPC request then the application wide failure
> handling (see slide #24) will notify the user about the error. There is no
> need for new events.

Well, possibly. If you like the idea of a system-wide error handler.
It's good for general or unexpected errors, but if I submit a form and
there are validation errors, I will probably want to provide more
localised feedback. Also, I might want to perform a follow-up action,
such as highlight a particular field with an error, or whatever. I
can't be sure when I receive a 'Error' event that the source was my
original request - the source will have been sent to the server and
back since then...

Anyway, there are ways to do it of course. I'll be interested to see
your solution if you make it public :)

David

Daniel Jue

unread,
Jul 16, 2009, 7:32:18 AM7/16/09
to Google-We...@googlegroups.com
Alejandro's source code is here:

http://code.google.com/p/puntosoft/

David Peterson

unread,
Jul 17, 2009, 11:06:11 AM7/17/09
to Google Web Toolkit
Fair point :)

Kwhit

unread,
Jul 17, 2009, 5:22:12 PM7/17/09
to Google Web Toolkit
On Jul 15, 9:36 pm, David Peterson <da...@randombits.org> wrote:
- Thinking further, I think it's better to separate the EventBus from
- the Command system somewhat. The reason being that generally, events
- are used to update on changes that have already happened, or are
about
- to happen. They don't trigger the actual event itself.

Yes I've been thinking about that.

Any user action that interacts with the server: sign in, create
account, update address, etc., has an asynchronous response. I find
myself tempted to wrap the service request in and make it synchronous
but that would be morally wrong and lead into all kinds of
difficulties in the details. So I've gone the other route...

My proof of concept implementation treats a click on the 'sign in'
button as an event which it fires and forgets to the event bug. Maybe
this goes too far in the other direction - time will tell. I'll post
my results as soon as I've got some real experience with it.

David Peterson

unread,
Jul 18, 2009, 10:32:49 PM7/18/09
to Google Web Toolkit
I really think it's a purely philosophical decision - I can see how it
would work fine with EventBus, I'm just choosing not to, basically.
For me the line in the sand is that events are about information,
commands are about action. Your mileage may vary :)

David

Eduardo Nunes

unread,
Jul 21, 2009, 3:16:54 PM7/21/09
to Google-We...@googlegroups.com
About the gwt-presenter library, I found some points that I would like
talk to you:
- When I extend WidgetPresenter/BasicPresenter I have to implement
many abstract methods, is it really necessary to set those methods as
abstract? Isn't it better to provide an empty default implementation?
I know that I can do it by myself but it's just a suggestion.
- Isn't it better to define the Place mechanism in the BasicPresenter
checking if the current object is a instanceof SomePlaceInterface
instead of calling directly getPlace?
- I didn't realize the meaning of the startProcessing and
stopProcessing methods in Display interface. Can you gimme some usage
example?

That's my 5cents, I think I will change my project to use your library
and keep it online just as an usage example.

If you want to take a look on it:
http://code.google.com/p/gwt-mvp-sample/source/browse/#svn/branches/gwt-presenter

Best regards,
--
Eduardo S. Nunes
http://e-nunes.com.br

Thomas Broyer

unread,
Jul 21, 2009, 6:07:55 PM7/21/09
to Google Web Toolkit


On 15 juil, 21:36, David Peterson <da...@randombits.org> wrote:
>
> Presenter Pattern API: http://code.google.com/p/gwt-presenter

I wouldn't have made the "place" a part of the presenter (it isn't any
different than the presenter registering itself a change handler on
History).
The whole point of the "place" service is to decouple your "URL
patterns" from your components: the place service just:
- listens to history change events, "interprets" them and fire
appropriate events on the event bus ("please display the contact with
ID=12345", "please display the list of contacts")
- listens to events fired by other components and updates the URL
(History.newItem(newToken, false)); for instance, when you click on a
contact in the contact list, the list fires a "picked contact (the one
with ID=12345)" event, some component listens to it and updates the
display to show the contact info, and the place service listens to it,
maps it to a history token and updates the History. Or maybe the
component that displays the contact fires a "contact displayed (the
one with ID=12345)" event, and the place service listens to this one
instead.

Maybe this fits into your gwt-dispatch project instead, but that's how
I would model the "place service".

Eduardo Nunes

unread,
Jul 21, 2009, 7:55:34 PM7/21/09
to Google-We...@googlegroups.com
Good point Thomas. So, the place service would directly call some
presenter or talk to the presenter by events.
Considering my sample application and the url (
http://host/bit.html#edit;issue=1 ):
- the place service would fire an IssueEditEvent with the issue id=1
- the main presenter would take this event and call the appropriated
method in the IssueEditPresenter

Thanks for the feedback Mr. Broyer, I will make a mix of the
gwt-presenter project and mine, implementing this place service as
well.

Best regards,
>
> Maybe this fits into your gwt-dispatch project instead, but that's how
> I would model the "place service".
> >
>



Jason A. Beranek

unread,
Jul 21, 2009, 10:07:54 PM7/21/09
to Google Web Toolkit
I've been looking at the place service as well, but while I don't
agree with exactly the structure in David Peterson's example, I'm not
sure if the place service should fire an IssueEditEvent that drives
some UI change. From the Ray Ryan presentation, my impression is the
Place Service functions as an abstraction between client code/widgets
and the History API allowing client code to decouple from the
specifics of parsing and generating history tokens. The Place Service
in that model is the sole handler of History events, and possibly one
of the limited set of interfaces that programmatically set History
(though you could use HyperLink widgets as the only means to control
the token, however this complicates the creation of tokens).

As for the structure of the Place object, one approach is to use a
simple key/value pair for the location, for example:

#key
#key/value

This seems to be the same approach used in the current Gmail, and
seems like a good approach for some navigation schemes. Personally,
I'd avoid more complex representation of Places, as it complicates
parsing and Place change processing. However, your mileage may vary.

-Jason

On Jul 21, 6:55 pm, Eduardo Nunes <esnu...@gmail.com> wrote:

Kwhit

unread,
Jul 22, 2009, 2:46:27 AM7/22/09
to Google Web Toolkit
A short update on the original posting.

I've now implemented the pattern I suggested in the original post in a
reference application and it's running.

My goals for doing the work were to address two issues:

1/ My GWT/GAE productivity: after a short learning curve it had sped
up but it slowed right down again

2/ I found it easier not to write unit tests (a dangerous state of
affairs) - they made the project messy, infiltrated the code, were
difficult to write and slow to run


The current implementation:

* Adds a generic RPC mechanism (the pipe)

* Doesn't use the command pattern. Instead everything is an event.
Selected events from the event bus are sent over the pipe and
responses are fired back. This makes the pipe invisible - no more
coding service interfaces

* I've added a layer (Stratus) on top of Bigtable-JDO inspired by
Grails create, find, update, delete

* Added a NullPipe and mock implementation of Stratus - I can now run
end-to-end testing: presenters to database - i.e. everything but the
composite itself without deploying to GAE. 7 unit test files run in
around 0.5 seconds and developing is fun again!


Findings so far

* Ray's presentation was really helpful

* Commands as events (aka asychronicity on steroids!): I'm kinda OK
with this. I'm aware of David's posting above so I'm not 100% sure
although still positive about my implementation. You do loose the
procedural feel of the service call and AsyncCallback return although
it is really asynchronous. I expected it to be difficult to test but
it's not. I need more experience with it

* I moved the definition of the Viewer (RR's Display interface) to the
Presentation interface. Sorry Ray, it was in the wrong place

* I dropped the idea of using HasClickHanders, HasValues, ... in favor
of methods like getPassword(), and addSignInClickHandler() in the
Viewer interface. I think it's a very elegant idea but it doesn't sit
well with EasyMock and I prefer tested code to elegant code and don't
think I loose much

* MVP is great, really easy to test and so, to develop

I still need to figure out a position on places / history (see posts
above). My real application makes heavy use of History and I like it a
lot. But I still don't have a comfortable pattern that joins the
viewers and history together yet.

Thomas Broyer

unread,
Jul 22, 2009, 4:51:43 AM7/22/09
to Google Web Toolkit


On 22 juil, 04:07, "Jason A. Beranek" <jason.bera...@gmail.com> wrote:
> I've been looking at the place service as well, but while I don't
> agree with exactly the structure in David Peterson's example, I'm not
> sure if the place service should fire an IssueEditEvent that drives
> some UI change. From the Ray Ryan presentation, my impression is the
> Place Service functions as an abstraction between client code/widgets
> and the History API allowing client code to decouple from the
> specifics of parsing and generating history tokens. The Place Service
> in that model is the sole handler of History events, and possibly one
> of the limited set of interfaces that programmatically set History
> (though you could use HyperLink widgets as the only means to control
> the token, however this complicates the creation of tokens).

Yeah, right, Ray talks about "place change events" and components that
could listen to those to be informed when they're "in use" or not and
unregister/re-register their other handlers on the event bus (it's
around 46:20 in the video).
He doesn't talk about how to communicate with the place service to
update the history token though. I'd say that either components have a
dependency on the place service and call its methods directly (and the
place service updates the history and fires a place change event to
notify other components), or they themselves fire place change events
and the place service listens to them.
But those "place change events" are not that different from the events
I described earlier ("picked contact (the one with ID=12345)")

> As for the structure of the Place object, one approach is to use a
> simple key/value pair for the location, for example:
>
> #key
> #key/value
>
> This seems to be the same approach used in the current Gmail,

Actually, in Gmail, it can also be "label/My+Label/message-id", but
it's still simply splittable on slashes to extract sub-parts.

> and
> seems like a good approach for some navigation schemes. Personally,
> I'd avoid more complex representation of Places, as it complicates
> parsing and Place change processing. However, your mileage may vary.

The Google Documentation Reader <http://code.google.com/docreader>
used to use XPointer-like tokens such as "p(project1,project2)s
(project1)t(topic)" and now uses query-string-like tokens such as
"p=project1,project2&s=project1&t=topic". They're IMO as easy to parse
as "path-like" tokens like Gmail uses; it's just a matter of taste
(and how you'd like to model your internal API)

Daniel Wellman

unread,
Jul 22, 2009, 7:59:14 AM7/22/09
to Google Web Toolkit
On Jul 22, 2:46 am, Kwhit <kwhitting...@gmail.com> wrote:
> * I dropped the idea of using HasClickHanders, HasValues, ... in favor
> of methods like getPassword(), and addSignInClickHandler() in the
> Viewer interface. I think it's a very elegant idea but it doesn't sit
> well with EasyMock and I prefer tested code to elegant code and don't
> think I loose much

I think this is an important point. By exposing the low-level
HasClickHandlers, HasValues, etc. interfaces you have to write very
"chatty" tests, and using mock objects to do this requires a lot of
set up of expectations. For testing widgets like a Phone Number
editor (in Ray's example) this level of coverage may be desirable, but
for a presenter for a larger screen, it may be unmanageable.

So it seems it's a tradeoff in how much test coverage you need --
expose the low-level HasXyz interfaces in your view if you need more
automated test code coverage, or use a gateway interface to the view
which exposes higher-level methods like getPassword(). Using this
gateway means you lose test coverage of which specific widgets are
wired to a given Presenter callback, but you may be able to live with
that risk (a quick manual exploratory test might give you that
confidence).

Martin Fowler talks a little bit about this in his MVP writings -- see
the page below, starting with this paragraph "One of the prime reasons
to use Supervising Controller is for testability..."
http://martinfowler.com/eaaDev/SupervisingPresenter.html

Dan

Jason A. Beranek

unread,
Jul 23, 2009, 12:33:06 AM7/23/09
to Google Web Toolkit
On Jul 22, 3:51 am, Thomas Broyer <t.bro...@gmail.com> wrote:
> They're IMO as easy to parse
> as "path-like" tokens like Gmail uses; it's just a matter of taste
> (and how you'd like to model your internal API)

Agree that the implementation depends on the model for an applications
internal API. Part of me thinks that most of the design patterns Ray
presented may not be generalizable into a Presenter, Place, EventBus,
or Command Pattern API library that would work for everyone. For
everyone who likes a simple key/value structure to place objects
(where any large paths are aspects of parsing a value token in an
application dependant way), there is someone who likes query-string
like tokens. For everyone who thinks an application wide event bus is
useful, there's someone that wants to partition an event bus into
specific components. And for everyone that wants a series of core
classes that represent all Presenter and View interfaces/objects,
there are individuals that will prefer to implement M-V-P in their own
classes without providing interfaces and abstractions.

You bring up a good point regarding preference, and I think its
relevant to this thread in considering that there isn't a clear cut
approach to the design patterns presented that is right or wrong for
any given application. Each developer must pick their poison, so to
speak, and make trade off's based on their concerns.

Respectfully,

Jason

Jason A. Beranek

unread,
Jul 23, 2009, 12:47:27 AM7/23/09
to Google Web Toolkit
On Jul 22, 6:59 am, Daniel Wellman <etl...@gmail.com> wrote:
> So it seems it's a tradeoff in how much test coverage you need --
> expose the low-level HasXyz interfaces in your view if you need more
> automated test code coverage, or use a gateway interface to the view
> which exposes higher-level methods like getPassword().  Using this
> gateway means you lose test coverage of which specific widgets are
> wired to a given Presenter callback, but you may be able to live with
> that risk (a quick manual exploratory test might give you that
> confidence).

If you think about it, there is more a spectrum than a clear
separation between HasXyz as a low-level interface and a gateway
interface to the view. Based on Ray's talk, the Display interface for
each presenter is in effect the Gateway interface for the View and the
HasClickHandler or HasValue interface components expose the expect
interaction with that object. While these appear to be low-level, it
all depends on how the View itself is implemented. For example, I
could have a display interface for a UI that displays a list of
contacts having a function like this:

interface Display {
...
HasSelectionHandlers<Integer> getSelectionButton(){}
..
}

The Display Gateway object specifies that the SelectionButton is
responsible for producing selection events that return the index of
the list item selected. However, from a UI perspective this could be
implemented as a selection on a ComboBox, an HTML List, response to
clicking on a FlexTable row, clicking on a Radio button, or even
clicking a CheckBox next to the list item and then clicking on a "Make
Selection" button object. The level of granularity depends, like you
said, on how much interaction you want testable using JUnit tests
rather than GWTTestCases, but it is not an either/or choice. I do see
value in having HasXyzHandlers interfaces returned in the View Gateway
interface as a way of testing asynchronous interaction is correct,
since asynchronous interaction cannot be statically verified at
compile time.

-Jason

Kwhit

unread,
Jul 23, 2009, 4:20:53 AM7/23/09
to Google Web Toolkit
I think Jason has hit the nail on the head.

The reason I got uncomfortable with the HasXxx's is that they expose
the internal workings of the Viewer (Display in RR's terms). The name
getSelectionButton() is a clue. The presenter doesn't and shouldn't
care about how the Viewer decides how to trip an action - it might be
by some convoluted means like a time out and then HasClickHandler
makes no sense.

The other thing that made me uncomfortable was where Display was
defined - in the Viewer implementation. As soon as I did a second
implementation: a mock object, I can see that something is going
wrong.

As a programmer I find myself being too focused on the internal view
when I should be looking at how consumers of an interface see it.
Guice for example sees it's core entities as injectors but I see them
as factories. As the consumer, the Presenter is the boss here and, for
example, a sign in Viewer only needs (g/s)etAccountName(), getPassword
() and a 'signIn' callback. The HasXxxx expose a whole lot of other
functionality that you don't want anybody using.

In summary
1/ Define your Presenter logic
2/ Define your Viewer interface
3/ Unit test your Presenter implementation
4/ Implement and test your Viewer


Kwhit

unread,
Jul 23, 2009, 4:25:41 AM7/23/09
to Google Web Toolkit
See above positing
...
2/ Define Viewer interface (without thinking about how the Viewer
might be implemented)
...

Thomas Broyer

unread,
Jul 23, 2009, 8:17:50 AM7/23/09
to Google Web Toolkit


On 23 juil, 10:20, Kwhit <kwhitting...@gmail.com> wrote:
> I think Jason has hit the nail on the head.
>
> The reason I got uncomfortable with the HasXxx's is that they expose
> the internal workings of the Viewer (Display in RR's terms). The name
> getSelectionButton() is a clue. The presenter doesn't and shouldn't
> care about how the Viewer decides how to trip an action - it might be
> by some convoluted means like a time out and then HasClickHandler
> makes no sense.

If you care about "modularization", then yes; but if you are more
pragmatic and only think about decoupling (to allow testing your
"presentation logic" separate from the actual "view"), then I don't
see a problem (much like whether your components know the "place
service" or the place service is rather an "optional module" that you
can plug in and out of your app without side effect apart from
"history management" // see above in this thread).

> The other thing that made me uncomfortable was where Display was
> defined - in the Viewer implementation.

Er, no, it's in the Presenter (slides 58 and 59).

> As a programmer I find myself being too focused on the internal view
> when I should be looking at how consumers of an interface see it.
> Guice for example sees it's core entities as injectors but I see them
> as factories. As the consumer, the Presenter is the boss here and, for
> example, a sign in Viewer only needs (g/s)etAccountName(), getPassword
> () and a 'signIn' callback. The HasXxxx expose a whole lot of other
> functionality that you don't want anybody using.

IMO, you're thinking here at a higher level.

If I have a text field (for the user name), password field and button
(to sign-in), and want the sign-in button to be automatically disabled
whenever one of the field is empty; then I need to listen for events
on the fields. This is part of the Presenter logic, because:
- it works whether the view is implemented in GWT (HTML) or Swing
- it works whether I use a text field or password field for the
password
- it works whether I use a Label, HTML, Button, CustomButton or
PushButton
- that's a behavior I that I want to be testable (this is the main
argument actually)
Here, HasValue<String> comes in very handy (instead of: getAccountName
() + addAccountNameChangeHandler(), etc.) what would be missing in GWT
is a "Enableable" interface for the button.

The point of Ray about MVP is about testability of your presentation
logic with "pure Java" JUnit tests. You still think in terms of
widgets but your don't have a dependency on the Widget class (which
has a dependency on com.google.gwt.dom.*, which uses JSNI and
therefore requires a GWTTestCase; on the other hand, DomEvent<?>, such
as ClickEvent, only use JSNI as part of the getNativeEvent(); you can
mock a ClickEvent by extending it and how it is used by other methods
such as preventDefault and stopPropagation, but the class can be
extended and the methods overriden if you really need your Presenter
to deal with them, and your MockHasClickHandlers would then pass such
a MockClickEvent to the presenter's ClickHandler).

It's just and only about how to organize your widgets code to make it
testable easily.

The goal isn't that your test be independent of the presenter's
internals (if the presenter doesn't even make use of the ClickEvent,
the mock HasClickHandlers could pass 'null' as an argument instead of
a MockClickEvent).
It isn't either that your presenter be independent of the view
"details" (if your first version didn't enable/disable the sign-in
button but instead show an alert if one of the fields were empty when
the button is clicked, you wouldn't need HasValue<String> and a
getAccountName would be enough; and the time you change your mind
about your presentation logic, you update both your presenter and view
code).

You can of course use MVP at a higher level too, but the whole point
of Ray is to not burn your event handlers inside your "view" and
instead use "abstract" interfaces

(updated with your followup mail)
> In summary
> 1/ Define your Presenter logic
> 2/ Define Viewer interface (without thinking about how the Viewer
> might be implemented)
> 3/ Unit test your Presenter implementation
> 4/ Implement and test your Viewer

I think you were right in your first mail: "define the Display/Viewer
interface" *thinking* about how you'll implement it, because your
presenter logic relies on it.

As I said, you're at a higher level here; thinking more about
modulalization/componentization and abstractions, than about
pragmatism and testability of your UI logic (don't put words in my
mouths: this is not a bad thing, just something different).

To continue the reasoning about this example: the presenter would,
when the sign-in button is clicked, make an RPC call to validate the
credentials. If I understand Ray's Command Pattern correctly, the RPC
call would be successful even if the credentials were wrong, with the
ValidateCredentialsResponse object containing the error (see slide
#62); so the SignInPresenter would have it's AsyncCallback#onSuccess
called and could handle the error by e.g. showing a message (the view
could show it next to the sign-in button for example). The generic
AsyncCallback#onFailure processing is only used for unexpected server
errors. On a successful login, then either the presenter or the
service (using a wrapping ServiceAsync implementation; but I think
this is actually useful merely for CRUD operations on data) would fire
a SignInEvent on the event bus.

Nathan Wells

unread,
Jul 23, 2009, 8:54:04 AM7/23/09
to Google Web Toolkit
Small note...

> could show it next to the sign-in button for example). The generic
> AsyncCallback#onFailure processing is only used for unexpected server
> errors. On a successful login, then either the presenter or the

If you prefer to have your failed authentication throw an exception
(which is true in my case) you can simply have the Presenter's
callback override the onFailure method, check for the specific
exception you want, then call super(caught) if you didn't get the
exception you were expecting.

Eduardo Nunes

unread,
Jul 23, 2009, 9:11:46 AM7/23/09
to Google-We...@googlegroups.com
Shouldn't the server errors be treated as unchecked exceptions
(extends RuntimeException)? Maybe a solution could be three methods,
one for failures (unchecked exceptions), one for errors (checked
exceptions) and another one for success.

What do you think?

Best regards,

Daniel Jue

unread,
Jul 23, 2009, 10:29:40 AM7/23/09
to Google-We...@googlegroups.com
@kwhittingham
I found your implementation interesting.


The current implementation:

* Adds a generic RPC mechanism (the pipe)

* Doesn't use the command pattern. Instead everything is an event.
Selected events from the event bus are sent over the pipe and
responses are fired back. This makes the pipe invisible - no more
coding service interfaces
 
I found myself thinking about this and then landing on the philosophically rocky shore of "cause and effect", and how to delineate an event from a command.  This was probably because I was thinking of the word "action", which uses the same neurons as"event" in my brain.

Are your responses also in the form of events, where the traditional response value is the "payload" of a new event object?  For either server error or validation error, are you sending back a different event, or setting a flag inside the expected return event?  
 

* I've added a layer (Stratus) on top of Bigtable-JDO inspired by
Grails create, find, update, delete

* Added a NullPipe and mock implementation of Stratus - I can now run
end-to-end testing: presenters to database - i.e. everything but the
composite itself without deploying to GAE. 7 unit test files run in
around 0.5 seconds and developing is fun again!


Findings so far

* Ray's presentation was really helpful

* Commands as events (aka asychronicity on steroids!): I'm kinda OK
with this. I'm aware of David's posting above so I'm not 100% sure
although still positive about my implementation. You do loose the
procedural feel of the service call and AsyncCallback return although
it is really asynchronous. I expected it to be difficult to test but
it's not. I need more experience with it

Unless you grew your event bus's intelligence, you would also lose batching.  Even undo could be tricky.  I'm guessing inside your event bus you have something like

if eventX.isRPCEvent() {
service.takethisEvent(eventx,new callback<Event>{...onsuccess(Event resultEvent){ fireEvent(resultEvent)}
};
}

Do you have a separate, server side event bus to do things like batching or compound events (Previously compound actions)?  Also do you ever have one event that goes to the server, but two events coming back? I guess your onSuccess could expect an ArrayList<Event> and just get back a list of size one in most cases. Then it would support multiple events back from the server, except it would get them all at one time.
 


* I moved the definition of the Viewer (RR's Display interface) to the
Presentation interface. Sorry Ray, it was in the wrong place

* I dropped the idea of using HasClickHanders, HasValues, ... in favor
of methods like getPassword(), and addSignInClickHandler() in the
Viewer interface. I think it's a very elegant idea but it doesn't sit
well with EasyMock and I prefer tested code to elegant code and don't
think I loose much

I also didn't like those two particular return types since my 3rd party widgets (Smartgwt)  don't support those interfaces.  And wrapping each 3rd party widget I want to use in an adapter class that implements those interfaces...it seems like too much work for the benefit.

 
I still need to figure out a position on places / history (see posts
above). My real application makes heavy use of History and I like it a
lot. But I still don't have a comfortable pattern that joins the
viewers and history together yet.
What pattern would you say you are using now?


Along with someone else in a previous email, I also did not understand the reason behind
void startProcessing(); and
void stopProcessing();

in the Display interface of gwt-presenter.  Is that intended for making the view/display modal or turning an animated gif on and off during an async call?


Kwhit

unread,
Jul 24, 2009, 3:56:22 AM7/24/09
to Google Web Toolkit
> Are your responses also in the form of events, where the traditional
> response value is the "payload" of a new event object?  For either server
> error or validation error, are you sending back a different event, or
> setting a flag inside the expected return event?

Yes currently all inter-component communications is via events on the
client side - the payload doesn't look like events on the server. I
did try it but dropped the idea of a server side event bus. Events are
not reused so different events come back from the server. It's
experimental - it works but I don't have enough experience yet to
claim it's a good or better idea.

I use 'modelettes' for want of a better word which are litle bits of
the core application model that travel twixt server and client. With
response time latency and keeping bandwidth at reasonable levels in
mind I want to keep what goes to the server in chunks (not like Google
Wave that can do character by character). What I think will be the
next big thing is a focus on services - encapsulation revisited but
for different reasons. This has led me to having 'service providers'
on the server as a layer above, and providing core business logic for,
the core model objects: Person, Account, ... The service providers
have a
"response = process(request)" interface. When the SPs are loaded they
announce which requests they would like to process to the server end
of the pipe which will call them when the requests come in.


> Unless you grew your event bus's intelligence, you would also lose
> batching.  Even undo could be tricky.  I'm guessing inside your event bus
> you have something like
> if eventX.isRPCEvent() {
> service.takethisEvent(eventx,new callback<Event>{...onsuccess(Event
> resultEvent){ fireEvent(resultEvent)}
>
> };
> }
Your're right. I'll try and think of a way of addressing this. It may
be that I have to step back and find a place for commands a bit.


> Do you have a separate, server side event bus to do things...

See above

> ...Also do you ever have one
> event that goes to the server, but two events coming back?...

Not yet. I've built in a mechanism for SPs to passively listen to
completed processing of requests which could be used to piggy back
events but I haven't used it yet (YAGNI?).


>> * I dropped the idea of using HasClickHanders, HasValues, ... in favor
> I also didn't like those two particular return types since my 3rd party
> widgets (Smartgwt)  don't support those interfaces.  And wrapping each 3rd

I'm reviewing this at the moment in the light of Thomas B's merciless
but very correct post above.


>> I still need to figure out a position on places / history (see posts
>What pattern would you say you are using now?

I am using History and think it's great. I don't have a clear,
describable pattern yet


> Along with someone else in a previous email, I also did not understand the
> reason behind void startProcessing(); and void stopProcessing();

Not sure

---
I'm going to try and post the code to the group next week so you can
look for yourself

Kwhit

unread,
Jul 24, 2009, 4:04:39 AM7/24/09
to Google Web Toolkit
On Jul 23, 3:11 pm, Eduardo Nunes <esnu...@gmail.com> wrote:
> Shouldn't the server errors be treated as unchecked exceptions
> (extends RuntimeException)? Maybe a solution could be three
methods,

I've found my self coding RE's for just about everything now. I think
they are the most undervalued part of the Java language during the
development phase. Example

try {
final File f = new File("Whatever);
...do something with file
} catch(final IOException e) {
throw new RuntimeException("Something went wrong with the file
operation", e);
}

The big advantages are you don't have to think about dealing with
problems whilst you're writing your 'happy day' code, you avoid
declaring exceptions which just put's off the inevitable and normally
shifts the problem into a place where you're not equipped to deal with
it and lastly: often times, especially in a stateless environment, a
RE is the right course of action.

It also travels from server to client in GAE/GWT which is good.

Eduardo Nunes

unread,
Jul 24, 2009, 10:11:57 AM7/24/09
to Google-We...@googlegroups.com
I use exceptions in this way:

- RuntimeException for all those things that shouldn't happen in a
normal environment. For example, databases/files problems, requests of
objects using wrong ids (something like the user changed the id in the
url to a wrong one). And I just shown a default error message.

- Exception for all things that can go wrong in a normal environment.
For example, the authentication method, a registration user that
checks for a unique username, etc.

Using this approach I can find bugs fast because I don't hide errors
(they will come directly to the log and the user screen) when
something goes wrong.

my 5c,

Eduardo Nunes

unread,
Jul 24, 2009, 10:14:32 AM7/24/09
to Google-We...@googlegroups.com
I call them BusinessException and BusinessUncheckedException

BusinessException has the message key and an array of parameters, so I
can build pretty error messages in the client side.

David Peterson

unread,
Jul 27, 2009, 10:18:33 AM7/27/09
to Google Web Toolkit
Hi all, I've been off-list for a bit. Good to see the discussion has
been continuing in my absense :)

For the record, I'm not in love with the current 'Place' manager
implementation in 'gwt-presenter'. I've gone through about 4 different
designs, and this is the one I hate the least so far. My needs were to
have a way to pass in parameters to the place location. However, using
a more 'REST'-like syntax, ala GMail, etc (ie. 'value/xxx/yyy', rather
than 'action:key=value', which is the current system) could work
better.

And as for tying in 'Place' to BasicPresenter, yeah, it could be moved
further down the tree, so you can skip it for Presenters that don't
have a place. PlacePresenter, perhaps?

Anyway, I'll be thinking further about the implementation this week.
Feel free to hit me with questions - I'll be trying to check this
thread in the coming days.

David

On Jul 25, 12:14 am, Eduardo Nunes <esnu...@gmail.com> wrote:
> I call them BusinessException and BusinessUncheckedException
>
> BusinessException has the message key and an array of parameters, so I
> can build pretty error messages in the client side.
>
>
>
> On Fri, Jul 24, 2009 at 11:11 AM, Eduardo Nunes<esnu...@gmail.com> wrote:
> > I use exceptions in this way:
>
> > - RuntimeException for all those things that shouldn't happen in a
> > normal environment. For example, databases/files problems, requests of
> > objects using wrong ids (something like the user changed the id in the
> > url to a wrong one). And I just shown a default error message.
>
> > - Exception for all things that can go wrong in a normal environment.
> > For example, the authentication method, a registration user that
> > checks for a unique username, etc.
>
> > Using this approach I can find bugs fast because I don't hide errors
> > (they will come directly to the log and the user screen) when
> > something goes wrong.
>
> > my 5c,
>
Reply all
Reply to author
Forward
0 new messages