In an attempt to orient myself and my colleagues with GWT, I've been reading up on GWT, trying things out, and blogging about them here. My goal is to start with simple use cases and build on to them with more complex ones. The way it's been working so far is that each post builds on the prior one.

Wednesday, February 17, 2010

Improving the View with Composite Interfaces

Looking back at the ContactDetailPresenter code, there is missing logic based on the initial requirements of the Contact List application. The ContactDetailPresenter does not update the Contact’s first name when the user updates the first name in the UI. In the ContactDetailPresenter.setContact() method, we set up a ChangeHandler to create a ContactUpdatedEvent and post it to the event bus. The user initiates this by updating the first name of the Contact. The problem is that no code in the ChangeHandler actually pulled the updated first name off the View and applied it to the Contact. Unfortunately, the current structure of the View provides us no means to get that updated first name. All it currently supports is the ability to listen for when the name changed via its HasChangeHandlers interface:

public interface ContactDetailView {
public HasChangeHandlers setFirstName(String firstName);
}


We set the name, but all we get back in return is the ability to add listeners for the change. We also need that returned interface to support getting the text out of the UI element where the user entered the name. We’ll introduce a new interface, TextInput, which encapsulates both of these capabilities: TextInput now has capabilities to both add change handlers and get text.



public interface TextInput extends HasChangeHandlers, HasText{

}

Note: HasChangeHandlers and HasText are both interfaces delivered in the core GWT library.


And we’ll have ContactDetailView.setFirstName() return this expanded interface.



public interface ContactDetailView {
public TextInput setFirstName(String firstName);
}


With this new TextInput interface, we can fix the issue in our Presenter and have the ChangeHandler pull the text out of the TextInput interface and apply it to the Contact:




public void setContact(final Contact contact){
final TextInput textInput = view.setFirstName(contact.getFirstName());
textInput.addChangeHandler(new ChangeHandler() {

public void onChange(ChangeEvent event) {
contact.setFirstName(textInput.getText());
eventBus.fireEvent(new ContactUpdatedEvent(contact));
}
});
}


In this post we explored a pattern to create a composite interface to give parts of a View multiple capabilities. We do this to support how a Presenter needs to interact with its corresponding View.

AppController and Event Handling

In the absence of any other object in our ContactList application, we’d send a Contact to the ContactDetailPresenter when a Contact was selected in the ContactListPresenter.

And if the user updates Joe’s first name to Joseph, we’d send a message back to the Contact List so that it displays Joseph instead of Joe.

image

And then Product Management might come along and say that the Browser Window title should reflect the selected Contact. In response, we’d add a BrowserWindowPresenter and wire things up to get that displaying what it should.

image

Everything in theory will work, but we are getting to a place where the UI components’ presenters are intertwined and dependent upon each other. ContactDetailPresenter needs a handle to ContactListPresenter and BrowserWindowPresenter in order to send them contact-updated notifications. ContactListPresenter needs a handle to ContactDetailPresenter and BrowserWindowPresenter in order to send them contact-selected notifications. It’s not too hard to imagine that, as a page gets more complex, the number of dependencies among the Presenters will grow. This means a couple things:

· This makes testing challenging. In order to test the ContactListPresenter behavior in isolation, we would need to mock the BrowserWindowPresenter and the ContactDetailPresenter.

· If we like the Contact Detail UI Component and decide it should be re-used on a different page, we’d have to do significant refactoring to decouple the Contact Detail UI Component from the Contact List UI Component and the Browser Window UI Component.

To address these dependency issues, we’ll introduce an AppController to coordinate messages between UI Components and we’ll build an Event Bus in to each presenter so that the AppController can register interest in the presenter events and can react accordingly.

With the AppController in place, the diagram now looks like so:

image

The event bus in each Presenter is how the AppController registers interest in event. Then when one presenter raises events, the AppController is notified so that it can instruct other presenter what to do. We’ve now addressed the two dependency issues raised above. We can test any presenter in isolation and we can use the Contact Details UI component in any page.

GWT Events: GWT has a built-in mechanism to do event-handling. GWT’s HandlerManager class can serve as an event bus. Presenters (or whoever) can register interest in particular events using the addHandler(EventHandler) method. After that, GwtEvents can be fired on to the HandlerManager using the fireEvent(Event) method, in which case the interested parties will be notified. GWT Events have 3 main components: a Type, an Event Definition, and an Event Handler. By use of Java generics, the Event Definition is tied to a particular Type and EventHandler. This ultimately prevents us from making mistakes like handling a particular event with the wrong event-handler.

We’ll now take a couple of the events discussed for the Contact Management application and see how the code would look using GWT. First, we’ll define the needed events, ContactUpdatedEvent and ContactSelectedEvent.

Given this, here are what the ContactUpdatedEvent and ContactSelectedEvent events could look like. The ContactUpdatedEvent will be constructed with a particular Contact and can dispatch to any ContactUpdatedEventHandler.


public class ContactUpdatedEvent extends
GwtEvent{
public Contact contact;
public ContactUpdatedEvent(Contact contact){
this.contact = contact;
}
public static final Type TYPE = new Type();
public static interface ContactUpdatedEventHandler extends EventHandler{
public void handleEvent(ContactUpdatedEvent contact);
}
@Override
protected void dispatch(ContactUpdatedEventHandler handler) {
handler.handleEvent(this);
}
@Override
public Type getAssociatedType() {
return TYPE;
}
public Contact getUpdatedContact(){
return contact;
}
}

Note: GwtEvent is a class delivered in the core GWT library. EventHandler and Type are interfaces delivered in the core GWT library.

And similarly, the ContactSelectedEvent will be constructed with a particular Contact and can dispatch to any ContactSelectedEventHandler.



public class ContactSelectedEvent extends
GwtEvent{
public Contact contact;
public ContactUpdatedEvent(Contact contact){
this.contact = contact;
}
public static final Type TYPE = new Type();
public static interface ContactUpdatedEventHandler extends EventHandler{
public void handleEvent(ContactUpdatedEvent contact);
}
@Override
protected void dispatch(ContactUpdatedEventHandler handler) {
handler.handleEvent(this);
}
@Override
public Type getAssociatedType() {
return TYPE;
}
public Contact getSelectedContact(){
return contact;
}
}


And that’s all we need to define events and event-handlers for use with each Presenter’s Event Bus. With that in place, we can now go in to our presenters and add code to post events on to the EventBus.



To accomplish this, the Contact Detail Presenter could now look like the code below. Notice it now has its own event bus and an onContactUpdated() event so the AppController can register interest in a ContactUpdatedEvent. And if the Contact is updated, it will post an event to the Event Bus telling it that a Contact was updated and the AppController will be notified and can react accordingly.



public class ContactDetailPresenter {
private ContactDetailView view;
private HandlerManager eventBus = new HandlerManager(null);
public ContactDetailPresenter(ContactDetailView view){
this.view = view;
}

public void setContact(final Contact contact){
final HasChangeHandlers hasChangeHandlers = view.setFirstName(contact.getFirstName());
hasChangeHandlers.addChangeHandler(new ChangeHandler() {

public void onChange(ChangeEvent event) {
eventBus.fireEvent(new ContactUpdatedEvent(contact));
}
});
}

public void onContactUpdated(ContactUpdatedEventHandler updatedEventHandler){
eventBus.addHandler(ContactUpdatedEvent.TYPE, updatedEventHandler);
}
}


With this in place, we can now imagine that the ContactList would take a similar approach to enable an AppController to handle a ContactSelectedEvent. Here’s some code from the App Controller that wires up the events:




public void wireUpEvents(){
contactList.onContactSelected(new ContactSelectedEventHandler() {

public void handleEvent(ContactSelectedEvent contactSelectedEvent) {
contactDetail.setContact(contactSelectedEvent.getSelectedContact());
}
});

contactDetail.onContactUpdated(new ContactUpdatedEventHandler() {

public void handleEvent(ContactUpdatedEvent contactUpdatedEvent) {
contactList.updateContact(contactUpdatedEvent.getUpdatedContact());
}
});
}


Here’s an approximate sequence showing the event-registration process:



image



And here’s an approximate sequence showing the event-handling:



image









Note on Application State: The examples in this post show event handlers being constructed with a Contact object. Depending upon the type of application being built, this may not be a good idea for all these event handlers in different Presenters to have a handle to the exact same object. It’s probably better to have application state managed in a single place and only let presenters have copies of this state. I’ll research application state some more and write a post on that when I have a pattern I’m comfortable with.











Note on changes to this post: This chapter is a version 2. I changed this chapter after reading this article http://code.google.com/webtoolkit/doc/latest/tutorial/mvp-architecture.html. In the first version, I had all UI Components listening on an application-wide event bus and there was no AppController. The ContactDetailPresenter listened for ContactSelectedEvents and would update itself when a ContactSelectedEvent was raised. This meant that the UI component was essentially built for pages that raised ContactSelectedEvents; after reading this article, I realized this coupling is unnecessary and potentially limiting. I like the AppController concept better so that it can be the thing handling events that any particular UI component raises. Now the AppController listens for the ContactSelectedEvent and simply tells the ContactDetailPresenter to present a particular Contact. The ContactDetailPresenter need to know nothing of ContactSelectedEvents. The one thing I did different from the article is that I have an event bus be wholly managed by a presenter; whereas, the article shows an application-wide event bus passed in to the presenters. I personally like the presenter-owned event bus better since the presenter simply support handlers (e.g. ContactListPresenter.onContactSelected()) only for those events it can fire. This, in my opinion, keeps the contract of the presenter more clear. This approach is similar to how Widgets deal with their events and tell its clients how, for example, they can register interest in an OnClick event.


Tuesday, February 16, 2010

Why should the View know nothing about the Model?

 

An advantage of coding in Java is that our code can be strongly-typed. Since our View represents the UI, perhaps we’d design the ContactListView to have a method to addContactToList where we pass it a strongly-typed element of the Model, Contact, and the ContactListView would, in turn, add an HTML anchor as a list item to the Contact list.


public interface ContactListView{
public void addContactToList(Contact contact);
}


But we said above that our View really shouldn’t know anything about the Model and passing Contact in to the View contradicts that. In a GWT world of strongly-typed things, why is this so? Why not pass Model objects to the View and return Model objects from the View when events are raised?



It’s mostly about testability. If we pass Model objects to the View and the UI is loosely typed, then that means the View is responsible for doing translation from the Model to the UI and vice-versa. “Translation” means logic and logic necessitates unit testing. UI is traditionally hard to test and GWT is no exception. (It’s a bit easier with GWT than other approaches, but it’s still much slower than being able to test independent of a UI.) Since UI is hard to test and the View ultimately represents the UI, the View is hard to test, also. So to maximize testability, we will give the responsibility of Model-to-UI translation to the Presenter. Although not the primary driver, there is also the possibility that leaving the Model out the View will improve reusability, the ability to use a particular View with different Models.



To ensure that our View doesn’t have to do a Model-to-UI translation, we could change our View to instead add a Contact to its contact list with a String instead of a Contact:



public interface ContactListView{
public void addContactToList(String contactFirstName);
}


Now the View->to->UI translation is trivial since we passed it data that it can trivially translate to HTML. And since it’s trivial, it’s not the end of the world if we don’t frequently regression test this aspect of the View. There’s not too much that can go wrong here. The Presenter is responsible for the binding/translation of the Model to the View and can have code like so:




public void setContactList(Collection contacts){
for (Contact contact : contacts){
contactListView.addContact(contact.getFirstName());
}
}


We can now test this translation by mocking the View and we could catch an error if, for example, we bind last name instead of first name from the Model to the View/UI.



This seems fine for sending data to the View, but how should we model events that are raised from the UI? We ultimately want to tie those events back to the Model. Going back to our example, when a user clicks on ‘Joe’, the HTML link, we ultimately want an event raised that ‘Joe’, the Contact, was clicked so that we can pass it, strongly-typed, to the ContactDetailPresenter. Since we passed a primitive String to the View, the View doesn’t know that a click on ‘Joe’ represents Joe the Contact. Remember one characteristic of our UI is to raise events and call out to do stuff. Since our UI can do this, it is reasonable that our View can do this too. In a GWT MVP world, we could accomplish this by returning a HasClickHandlers interface from the addContactToList() method. With this interface, the Presenter can add handlers for click events.




public interface ContactListView{
public HasClickHandlers addContactToList(String contactFirstName);
}


Note: HasClickHandlers is an interface delivered in the core GWT library.

Now when the Presenter does a Model->View translation, it can also add a listener/handler to click-events in a strongly-typed way. Here is some code we could now write in the ContactListPresenter. Notice that a click-handler is added for each Contact added to the view.




public void setContactList(Collection contacts){
for (final Contact contact : contacts){
HasClickHandlers hasClickHandlers = contactListView.addContact(contact.getName());

hasClickHandlers.addClickHandler(new ClickHandler() {

public void onClick(ClickEvent event) {
// do something with the strongly-typed Contact

}
});

}
}


Now our ContactListPresenter has done a full Model -> UI translation for rendering and a UI -> Model translation on event-handling. The View has no logic in it specific to the Model. (In fact, we haven’t even actually implemented our View yet.) All the View needs to do is accept UI-primitive data and raise UI-primitive events to those listening for them. And back to the testability concerns, we can unit test all the Model <-> UI translation without testing the View. This is a good thing since, as we discussed before, the View is more challenging to test.



Similarly for the ContactDetailView, it could have a View that looks like the following to the ContactDetailPresenter can listen for changes the user makes to the Contact’s first name:




public interface ContactDetailView {
public HasChangeHandlers setFirstName(String firstName);
}

Note: HasChangeHandlers is an interface delivered in the core GWT library.

And a ContactDetailPresenter could interact with it like so:




public void setContact(final Contact contact){
HasChangeHandlers changeHandlers = view.setFirstName(contact.getName());
changeHandlers.addChangeHandler(new ChangeHandler() {

public void onChange(ChangeEvent event) {
// do something with the strongly-typed Contact
}
});
}

MVP

 

The approach we’ll use to model this application is MVP, Model/View/Presenter.

Here, the Presenter sits between the Model and the View. The View knows nothing of the Presenter and the View knows nothing of the Model. This is actually a variation of MVP called Passive View (see Martin Fowler’s Passive View write-up for more details http://martinfowler.com/eaaDev/PassiveScreen.html).

For the purposes of this discussion, we’ll refer to all the functionality related to the left-hand Contact List as the ‘Contact List UI Component’ and all the functionality related to the right-hand Contact Detail as the ‘Contact Detail UI Component’. Each UI Component will have an M, a V, and a P. Within each of those UI components, we’ll explore the responsibilities and distinctions between their respective Models, Views, and Presenters. For the Contact List UI Component, we can think of it mapping to MVP in this way:

image

ContactListModel

The Model is a strongly-typed representation of the data to display in the UI Component. For both UI components, this is based on a Contact, a fairly simply bean that holds the attributes of a Contact.

ContactListView

In the MVP approach, the core responsibility of the View is to represent the user interface. User interfaces are very loosely typed. In the HTML world for our Contact List, this ultimately ends up being a String on a page, something like <a>Jim</a>, an element in the DOM, and an onClick event that can call out to do stuff.

ContactListPresenter

The ContactListModel is a strongly-typed data holder and the ContactListView is just the primitive aspects of the user interface. This leaves the rest of the responsibilities of the UI component to the ContactListPresenter:

· Translating the Model to the View for display. For example, taking the first name String from a Contact object and passing that String in to the ContactListView.

· Translating the View to the Model for updates. If for example, the user could update the user’s name directly from the Contact List, the Presenter would take the String entered and put that in to the Contact object’s first name attribute.

· Translate actions the user takes on their interface in to strongly-typed events that can be emitted out of the Presenter. What does it mean to be a strongly-typed event? Our text-based user interface can do little more than tell us that “Jim”, the String, was clicked. However, all our Java business logic really wants to deal with is meaningful objects: in this case, the Contact Model. The Presenter’s responsibility will be to convert the View action indicating “Jim, the String, was clicked” in to a Presenter event indicating that “Jim, the Contact, was clicked”.

· The ContactListPresenter will not only emit events such as “the user clicked on Jim”. It will also be listening for events emitted by other presenters in case those events need to change the View of the Contact List UI Component. For example, if the ContactDetailPresenter could emit an event that a Contact was changed, the ContactListPresenter would listen for that event so it could send appropriate parts of the updated Contact in to the ContactListView.

We’ll look at code samples later about how all these responsibilities can be fulfilled in GWT.

Design by Example

 

In the subsequent sections, we will talk about GWT design concepts through the use of a sample application.

We are trying to build an interactive web page. This means we have some display and, based on certain events, actions occur. Events are typically initiated by user interaction. Actions typically involve changing the display and/or doing an AJAX call to post/request some data.

Here’s an example of an interactive web page, a Contact List application. The interactive aspects are that 1) a user can click on a contact in the left-hand list and that will cause the Contact Details to show the selected Contact and 2) a user can update the Contact’s name in the right-hand side and it will update the list so that it shows the new name for the Contact.

image

Introduction

The upcoming set of posts are intended to discuss approaches for designing and developing interactive web pages using GWT (Google Web Toolkit). Most of this information is simply rehashed from various sources, but I’m rehashing again since 1) I didn’t see this all in one place and 2) the rehashing process gives me a better understanding of what is going on anyway.

The following are resources I used as I researched this:

http://robvanmaris.jteam.nl/2008/03/09/test-driven-development-for-gwt-ui-code
    Test driven development for GWT UI code

http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
    Google Web Toolkit Architecture: Best Practices For Architecting Your GWT App

http://easymock.org/Documentation.html
    EasyMock Documentation


http://martinfowler.com/eaaDev/PassiveScreen.html
    Passive View


http://vinaytechs.blogspot.com/2009/09/google-web-toolkit-hosted-vs-web-mode.html
Google Web Toolkit – Hosted vs. Web Mode

Followers