GWT Enterprise Patterns

Arya MirInternet and Web Development

Feb 12, 2012 (5 years and 4 months ago)

919 views



GWT Enterprise Patterns

Spencer Gibb

Sr. Software Engineer for LDS Church

12 Years Experience

E-commerce

Defense

Contractor

http://spencer.gibb.us

Heavy Google User

Google Apps for your Domain, App Engine, GWT

General Open Source Software User


If you remember nothing else...

Get browser history right, and get it right early

Use an Event Bus to fight spaghetti

DI + MVP

Dependency Injection

Model / View / Presenter


Three major themes

Embrace asynchrony

Always be decoupling

Strive to achieve statelessness


Event Bus

Everything is on the Event Bus

RPC

Results

Failures

Locations (Browser History)

View Presenter communication

Simpler Event code than GWT Events


EventBus GWT Event Style
public class MyEvent extends GwtEvent<MyEventHandler> {

public interface MyEventHandler extends EventHandler {

void onAddNewIssue(MyEvent event);

}

private static Type<MyEventHandler> TYPE =

new Type<MyEventHandler>();

public MyEvent() { }

public final Type<MyEventHandler> getAssociatedType() {

return TYPE;

}

protected void dispatch(MyEventHandler handler) {

handler.onAddNewIssue(this);

}
}


EventBus Simplified Events

Type Safe

getTypeObject is the key used by EventBus to
get handlers for particular event types rather
than the static TYPE.
public class MyEvent extends Event<String, MyEvent.Handler> {

public static abstract class Handler

extends EventHandler<MyEvent> {

public Object getTypeObject() {

return MyEvent.class;

}

}

public MyEvent(String data) {

super(data);

}
}




Command Pattern

GWT RPC Service implementation
DefaultDispatch

Commands

class SayHelloCommand implements
Command<HelloResults>

Results

class HelloResult implements Result

Reusable Result Objects

StringResult, LongResult etc...


Command Pattern Cont.

Command Handler

SayHelloCommandHandler implements
CommandHandler<SayHelloCommand, SayHelloResult>

One to one with a command/result pair

SayHelloResult execute(SayHelloCommand cmd)

Multi-Command Handler

Multiple commands in One class

Lose some type safety, gain flexibility
Class Handler extends MultiCommandHandler {
SayHelloResult hello(SayHelloCommand cmd) {}
GetHelloResult getHello(GetHelloCommand cmd) {}
}


Model, View, Presenter - MVP

Presenter defines View interface via GWT Has*
interfaces

Communication between View and Presenter is
via GWT Has* interfaces or Events

RPC done in Presenter

NO
GUI in Presenter


MVC


MVP


Presenter

Coordinates Events

Adds external behavior to view

RPC

Intra-app events
HelloPresenter extends

AbstractPresenter <HelloPresenter.View, CommandEventBus> {

class View extends WidgetView {

HasText getName();

//...

}

//...
}


View

All GUI work done here

UI Binder or widgets directly

Respond to Events on the EventBus
HelloViewImpl extends

AbstractWidgetView <CommandEventBus>

implements HelloPresenter.View {

HasText name;

//...

}

//...
}


Locations (GWT History)

Bookmarkability and browser back button

http://localhost/app#hello/joe

Gmail style positional parameters

All done via the event bus

Must be bootstrapped in EntryPoint

eventBus.changeLocation(“hello”, “fred”)

eventBus.add(new Location.Handler(“hello”) {

public void handle(Location location) {

location.getParam(0); }}


Dependency Injection in GWT

Gin on Guice (Compile time injection)

@Inject constructor injection

Event Bus in to Views and Presenters

Views in to Presenters

Default Presenter for Entry Point

View view = injector.getHelloPresenter().getView();
RootLayoutPanel.get().add(view.getImpl());


Integration

Appengine / JDO

JPA

Spring

Future GWT integration!

Guice

GIN (Gwt INjection)

Gilead (Generic Light Entity Adapter)

Maven

Eclipse (GWT/Appengine Plugin)


Wrap Up

Demo

Questions & Answers

http://gwt-enterprise-patterns.googlecode.com





1
GWT Enterprise Patterns

Spencer Gibb

Sr. Software Engineer for LDS Church

12 Years Experience

E-commerce

Defense

Contractor

http://spencer.gibb.us

Heavy Google User

Google Apps for your Domain, App Engine, GWT

General Open Source Software User
Looking to buy an older t-mobile android phone





2
If you remember nothing else...

Get browser history right, and get it right early

Use an Event Bus to fight spaghetti

DI + MVP

Dependency Injection

Model / View / Presenter
Borrowed From Google I/O Presentation
Who reviewed GWT Best Practices session from
Google IO?
My work is based off of that work
I took the event bus concept a little further





3
Three major themes

Embrace asynchrony

Always be decoupling

Strive to achieve statelessness
Borrowed From Google I/O Presentation
I broke some of these rules in the presentation





4
Event Bus

Everything is on the Event Bus

RPC

Results

Failures

Locations (Browser History)

View Presenter communication

Simpler Event code than GWT Events
It was very comfortable to put command, results,
locations, errors and general messages on the event
bus
The gwt HandlerManager that is viewed as the default
event bus can be unweildy
Custom events are more complex using
HandlerManager





5
EventBus GWT Event Style
public class MyEvent extends GwtEvent<MyEventHandler> {

public interface MyEventHandler extends EventHandler {

void onAddNewIssue(MyEvent event);

}

private static Type<MyEventHandler> TYPE =

new Type<MyEventHandler>();

public MyEvent() { }

public final Type<MyEventHandler> getAssociatedType() {

return TYPE;

}

protected void dispatch(MyEventHandler handler) {

handler.onAddNewIssue(this);

}
}
I didn't like having to implement the TYPE variable,
though I know why they did because of GWT's lack
of reflection





6
EventBus Simplified Events

Type Safe

getTypeObject is the key used by EventBus to
get handlers for particular event types rather
than the static TYPE.
public class MyEvent extends Event<String, MyEvent.Handler> {

public static abstract class Handler

extends EventHandler<MyEvent> {

public Object getTypeObject() {

return MyEvent.class;

}

}

public MyEvent(String data) {

super(data);

}
}
All the handlers followed the same pattern so I made a
generic one that simplified things
I use handlers by creating anonymous inner classes.
My custom events allowed for reusing results that we
will see later





7
Borrowed From Google I/O Presentation
The event bus allows for a high degree of decoupling
It made some possibly difficult things rather easy to do





8
Command Pattern

GWT RPC Service implementation
DefaultDispatch

Commands

class SayHelloCommand implements
Command<HelloResults>

Results

class HelloResult implements Result

Reusable Result Objects

StringResult, LongResult etc...
One object in, one object out
A dispatch gwt rpc service handles all server side
events
My custom events allow for resuable results, so you
can listen for the results of a particular command
rather than just results (though that may be desired)
http://en.wikipedia.org/wiki/Command_pattern





9
Command Pattern Cont.

Command Handler

SayHelloCommandHandler implements
CommandHandler<SayHelloCommand, SayHelloResult>

One to one with a command/result pair

SayHelloResult execute(SayHelloCommand cmd)

Multi-Command Handler

Multiple commands in One class

Lose some type safety, gain flexibility
Class Handler extends MultiCommandHandler {
SayHelloResult hello(SayHelloCommand cmd) {}
GetHelloResult getHello(GetHelloCommand cmd) {}
}
Seemed kind of like struts 1 to me
Use spring or guice to wire all your command handlers
to the dispatch
More work could be done here
More complex workflows via annotations





10
Model, View, Presenter - MVP

Presenter defines View interface via GWT Has*
interfaces

Communication between View and Presenter is
via GWT Has* interfaces or Events

RPC done in Presenter

NO
GUI in Presenter
I am a newbee here
Model-view-presenter (MVP) is a user interface design pattern engineered to
facilitate automated unit testing and improve the separation of concerns in
presentation logic.

* The model is an interface defining the data to be displayed or otherwise
acted upon in the user interface.

* The view is an interface that displays data (the model) and routes user
commands (events) to the presenter to act upon that data.

* The presenter acts upon the model and the view. It retrieves data from
repositories (the model), persists it, and formats it for display in the view.





11
MVC
Borrowed From Google I/O Presentation





12
MVP
Borrowed From Google I/O Presentation





13
Presenter

Coordinates Events

Adds external behavior to view

RPC

Intra-app events
HelloPresenter extends

AbstractPresenter <HelloPresenter.View, CommandEventBus> {

class View extends WidgetView {

HasText getName();

//...

}

//...
}
Similar to controller
Lots of event bus listeners and firings





14
View

All GUI work done here

UI Binder or widgets directly

Respond to Events on the EventBus
HelloViewImpl extends

AbstractWidgetView <CommandEventBus>

implements HelloPresenter.View {

HasText name;

//...

}

//...
}
Anything from the client.ui package
UI Binder is cool, simplifies views to behavior and not
layout





15
Locations (GWT History)

Bookmarkability and browser back button

http://localhost/app#hello/joe

Gmail style positional parameters

All done via the event bus

Must be bootstrapped in EntryPoint

eventBus.changeLocation(“hello”, “fred”)

eventBus.add(new Location.Handler(“hello”) {

public void handle(Location location) {

location.getParam(0); }}
Difficult to understand at first
Master location manager that delegates to children
Gwt-presenter project uses and interface that children
notify parents





16
Dependency Injection in GWT

Gin on Guice (Compile time injection)

@Inject constructor injection

Event Bus in to Views and Presenters

Views in to Presenters

Default Presenter for Entry Point

View view = injector.getHelloPresenter().getView();
RootLayoutPanel.get().add(view.getImpl());





17
Integration

Appengine / JDO

JPA

Spring

Future GWT integration!

Guice

GIN (Gwt INjection)

Gilead (Generic Light Entity Adapter)

Maven

Eclipse (GWT/Appengine Plugin)
The maven repositories were difficult.
Some things hosted in a local repo
GWT maven plugin works well
GWT 2.0
Some quirks when maven creates eclipse files





18
Wrap Up

Demo

Questions & Answers

http://gwt-enterprise-patterns.googlecode.com