107
GWT Architectures and Lessons Learned Dipl. Wi.-Ing. Papick Garcia Taboada pgt technology scouting GmbH http://pgt.de Orientation in Objects GmbH http://oio.de

Javaland 2014 / GWT architectures and lessons learned

Embed Size (px)

DESCRIPTION

Talk at Javaland 2014 about GWT architectures and lessons learned

Citation preview

Page 1: Javaland 2014 / GWT architectures and lessons learned

GWT Architectures and Lessons Learned

Dipl. Wi.-Ing. Papick Garcia Taboada

pgt technology scouting GmbH!http://pgt.deOrientation in Objects GmbH!http://oio.de

Page 2: Javaland 2014 / GWT architectures and lessons learned

‣GWT Development

‣Basics

‣Structuring the UI

‣Talking to the server

Page 3: Javaland 2014 / GWT architectures and lessons learned

Shift happened

Java development, JS deployment,

Async, RPC,

RIA/ single page, ...

Page 4: Javaland 2014 / GWT architectures and lessons learned

Web 2.0 ? development is all about…

!

…js …html …css

!

none of it !

…jcp …oracle … IBM

… backend

Page 5: Javaland 2014 / GWT architectures and lessons learned

what is a GWT application?

a chunk of JS that does a lot of DOM manipulation to create web

applications

Page 6: Javaland 2014 / GWT architectures and lessons learned

Widget t = new TextBox(); !

RootPanel.get().add(t);

UI component model

Browser Composite

Components

Page 7: Javaland 2014 / GWT architectures and lessons learned

Architecture shift

Web applications

Model 2 web applications

Rich internet applications

+ testability!+ maintainance!+ product development

Page 8: Javaland 2014 / GWT architectures and lessons learned

Browser Server

user action

full html response

full html response

full html response

user action

user action

classi

c web !

development

Page 9: Javaland 2014 / GWT architectures and lessons learned

Browser Server

event

first request

full html response

data

data request

data

data request

event

event

event

RIA web

development

Page 10: Javaland 2014 / GWT architectures and lessons learned

Web frameworks

Page 11: Javaland 2014 / GWT architectures and lessons learned

low level, generic tools

Page 12: Javaland 2014 / GWT architectures and lessons learned

let‘s build big things

Page 13: Javaland 2014 / GWT architectures and lessons learned

TextBox t0 = new TextBox(); TextBox t1 = new TextBox(); TextBox t2 = new TextBox(); TextBox t3 = new TextBox(); TextBox t4 = new TextBox();

VerticalPanel... SplitPanel... ScrollPanel

RootPanel.get().add(mainPanel);

Page 14: Javaland 2014 / GWT architectures and lessons learned

maintainance hell

Page 15: Javaland 2014 / GWT architectures and lessons learned

MacGyverAll he needed was a ballpoint

pen and a paper clip

Page 16: Javaland 2014 / GWT architectures and lessons learned

Ops

Page 17: Javaland 2014 / GWT architectures and lessons learned

Widget t = new TextBox(); !

RootPanel.get().add(t);

not enough…

Page 18: Javaland 2014 / GWT architectures and lessons learned

app-framework wizardry needed

Page 19: Javaland 2014 / GWT architectures and lessons learned

‣GWT Development

‣Basics

‣Structuring the UI

‣Talking to the server

Page 20: Javaland 2014 / GWT architectures and lessons learned

GWT DEVELOPMENT IS COMPLICATED HOT NEW STUFF.

Page 21: Javaland 2014 / GWT architectures and lessons learned

NOT REALLY

Page 22: Javaland 2014 / GWT architectures and lessons learned

GWT development is not new, but different

WHY?

Page 23: Javaland 2014 / GWT architectures and lessons learned

WEB DEVELOPMENT IS NOT NEW...1)

Page 24: Javaland 2014 / GWT architectures and lessons learned

THERE IS NOT A MOMENT TO LOOSETHERE IS NOT A MOMENT TO LOOSEJan 2000 Jan 2005

XHTML 1.0Jan 2000

HTML 4.0.1Dez 1999

CSS 2Mai 1998

HTML 4.0 updateApril 1998

XHTML 1.1Mai 2001

HTML 2.0November 1995

HTML 4.0Dezember 1997

Java EE 1.2Dez 1999

JDK 1.1Feb 1997

Internet Explorer 6Aug 2001

JDK 1.0Jan 1996

CSS 2.1Feb 2004 – Jun 2011

CSS level 2 revision 1, often referred to as "CSS 2.1", fixes errors in CSS 2, removes poorly supported or not fully interoperable features and adds already-implemented browser extensions to the specification. In order to comply with the W3C Process for standardizing technical specifications, CSS 2.1 went back and forth between Working Draft status and Candidate Recommendation status for many years.

J2SE 1.2Dez 1998

J2SE 1.3Mai 2000

CSS 1Dez 1996

HTML 3.2Januar 1997

Page 25: Javaland 2014 / GWT architectures and lessons learned

RICH CLIENT DEVELOPMENT

IS NOT NEW EITHER2)

Page 26: Javaland 2014 / GWT architectures and lessons learned

nothing new here

Page 27: Javaland 2014 / GWT architectures and lessons learned

nothing new here too

Jan 2007

Page 28: Javaland 2014 / GWT architectures and lessons learned

Look! YES! This is my code!

Page 29: Javaland 2014 / GWT architectures and lessons learned

It’s all aboutsoftware engineering

Page 30: Javaland 2014 / GWT architectures and lessons learned

Just a few tips

Page 31: Javaland 2014 / GWT architectures and lessons learned

USE MVP!You will get used to it

Page 32: Javaland 2014 / GWT architectures and lessons learned

event bus pleasehttp://jarrettws.blogspot.de/2010/05/public-transport.html

Page 33: Javaland 2014 / GWT architectures and lessons learned

eventbus.fireEvent( NotificationEvent.info( "Daten wurden erfolgreich gespeichert"

) );

Page 34: Javaland 2014 / GWT architectures and lessons learned

SINGLETON don‘t public static instance

Page 35: Javaland 2014 / GWT architectures and lessons learned

BUT ON IE 6 IT IS SO SLOW!

Page 36: Javaland 2014 / GWT architectures and lessons learned

BUT ON IE 7 IT IS SO SLOW!

Page 37: Javaland 2014 / GWT architectures and lessons learned

BUT ON IE 8 IT IS SO SLOW!

Page 38: Javaland 2014 / GWT architectures and lessons learned

BUT ON IE 9 IT IS SO SLOW!

Page 39: Javaland 2014 / GWT architectures and lessons learned

DID ANYONE TEST ON IE / SURFACE?

Page 40: Javaland 2014 / GWT architectures and lessons learned

browsers day to day job

Page 41: Javaland 2014 / GWT architectures and lessons learned

too many HTTP requests

Page 42: Javaland 2014 / GWT architectures and lessons learned

WTF?

> 2400 DOM elements

Page 43: Javaland 2014 / GWT architectures and lessons learned

too many widgets

Page 44: Javaland 2014 / GWT architectures and lessons learned

use large HTML chunks

Page 45: Javaland 2014 / GWT architectures and lessons learned

use large HTML chunks

Page 46: Javaland 2014 / GWT architectures and lessons learned

too many widgets ain‘t good

Page 47: Javaland 2014 / GWT architectures and lessons learned

a Widget is a JS thing holding a DOM element

<div />

Page 48: Javaland 2014 / GWT architectures and lessons learned

CREATE CUSTOM WIDGETS

don‘t extend FlextTable

don‘t extend VerticalPanel

don‘t extend SimplePanel

CREATE CUSTOM EVENTS

extend composite!!!

Page 49: Javaland 2014 / GWT architectures and lessons learned

the new native, do it in CSS

@-webkit-keyframes redPulse { from { box-shadow: 0px 0px 2px #ff0033; } 50% { box-shadow: 0px 0px 10px #ff0033; } to {

box-shadow: 0px 0px 2px #ff0033; } }

Page 50: Javaland 2014 / GWT architectures and lessons learned

use LayoutPanel

<g:LayoutPanel styleName="{B.style.mainContent}"> <g:layer left="0" right="340px" top="0" height="50%"> <g:SimpleLayoutPanel styleName="{B.style.mainWidget}" addStyleNames="{B.style.termineGlow}"> <ux:DashboardTermineDataGrid ui:field="terminetable" styleName="{B.style.mainWidgetContent}" /> </g:SimpleLayoutPanel> </g:layer> <g:layer right="0" width="340px" top="0" height="50%"> <g:SimpleLayoutPanel styleName="{B.style.mainWidget}" addStyleNames="{B.style.finanzenGlow}"> <ux:KWStatsDataGrid ui:field="statstable" styleName="{B.style.mainWidgetContent}" /> </g:SimpleLayoutPanel> </g:layer> <g:layer right="0" left="0" bottom="0" height="50%"> <g:SimpleLayoutPanel styleName="{B.style.mainWidget}" addStyleNames="{B.style.uebersichtGlow}"> <ux:WartelisteDataGrid ui:field="wartelistetable" styleName="{B.style.mainWidgetContent}" /> </g:SimpleLayoutPanel> </g:layer> </g:LayoutPanel>

Page 51: Javaland 2014 / GWT architectures and lessons learned

‣GWT Development

‣Basics

‣Structuring the UI

‣Talking to the server

Page 52: Javaland 2014 / GWT architectures and lessons learned

„just do it“ pattern

„View A“„View B“

mainPanel.setWiget( aWidget );

mainPanel.setWiget( bWidget );

some action

?

Page 53: Javaland 2014 / GWT architectures and lessons learned

hard to maintain

Page 54: Javaland 2014 / GWT architectures and lessons learned

history management

from day one! !

back button and refresh as a feature

(not a catastrophe)

Page 55: Javaland 2014 / GWT architectures and lessons learned

Keep It Stupid Simple

• use PLACES framework for main level navigation

• if you really need to, nest activities for a second level. try not to.

• use dialogs for user input, showing data. dialogs are easily reused.

Page 56: Javaland 2014 / GWT architectures and lessons learned

EXAMPLE

Page 57: Javaland 2014 / GWT architectures and lessons learned
Page 58: Javaland 2014 / GWT architectures and lessons learned

top menue bound to places framework

Page 59: Javaland 2014 / GWT architectures and lessons learned

switching between places with fade in and out

Page 60: Javaland 2014 / GWT architectures and lessons learned

teach user to wait until application is ready again

Page 61: Javaland 2014 / GWT architectures and lessons learned

gives us enough time to load the required content

300ms out 500ms in

Page 62: Javaland 2014 / GWT architectures and lessons learned
Page 63: Javaland 2014 / GWT architectures and lessons learned

Components inside of

„activity“ fire non public,

custom events

Page 64: Javaland 2014 / GWT architectures and lessons learned

datepicker sends WEEK

selected event

Page 65: Javaland 2014 / GWT architectures and lessons learned

presenter may goto itself, view may be cached

Page 66: Javaland 2014 / GWT architectures and lessons learned

#ashtag?!?

Page 67: Javaland 2014 / GWT architectures and lessons learned

STATELESS VIEW !

URL contains EVERYTHING needed to rebuild view

user hits reload GWT apps

starts, activity gets fired

presenter loads data from

server

view is back again

Page 68: Javaland 2014 / GWT architectures and lessons learned

some actions don‘t require PLACE navigation at all

Page 69: Javaland 2014 / GWT architectures and lessons learned

use POPUPS/ DIALOGS to stay ABOVE navigation

Page 70: Javaland 2014 / GWT architectures and lessons learned

let POPUPS/ DIALOGS move slowly into view

pin POPUPS to one side of the

window

Page 71: Javaland 2014 / GWT architectures and lessons learned

Don‘t move your user away from his „PLACE“

unless you have to.

Search DIALOG slides in from right side, stays on TOP

Page 72: Javaland 2014 / GWT architectures and lessons learned

Navigation should not hurt

• The application shown uses only 3 levels of navigation, DOES NOT NEED MORE

• PLACES used for bookmarkable entry points/ back button navigation consistency

• Activities should be STATELESS, to survive page reloads

• Learn from OTHERS, lookout for hashtags…

Page 73: Javaland 2014 / GWT architectures and lessons learned

Once upon a time, a young good designer did a good looking design...

‣ he will be using photoshop or dreamweaver !

‣ he will not use the software !

‣ he will not build the software !

‣ he will not maintain the software

Page 74: Javaland 2014 / GWT architectures and lessons learned

BEFORE YOU ADD THE LOGO TO THE TOP

how many pixels do your USERS have?

the designer or marketing guy using photoshop is probably sitting in front

of a 27“ apple cinema display

Page 75: Javaland 2014 / GWT architectures and lessons learned

‣GWT Development

‣Basics

‣Structuring the UI

‣Talking to the server

Page 76: Javaland 2014 / GWT architectures and lessons learned

GWT-RPC is a good solution if handled with care

SomeResult someMethodName(SomeParameter spo)

GWT-RPC binds many

methods into one interface

Interface Versioning is a monstrous

thing

Page 77: Javaland 2014 / GWT architectures and lessons learned

SomeResult someMethodName(SomeParameter spo)

this will be an object

this will be an object too

Page 78: Javaland 2014 / GWT architectures and lessons learned

SomeResult someMethodName(SomeParameter spo)

the method names bind the requests to the result

typesafety all the way

Page 79: Javaland 2014 / GWT architectures and lessons learned

USING GENERICS FOR !

TYPESAFETY, !

GET RID OF METHODS !

AND INTERFACES

Java Generics FAQ !400 pages.

PRO TIP:

Page 80: Javaland 2014 / GWT architectures and lessons learned

<A extends Action<R>, R extends Result> R execute(A action);

now we just have one interface with one method

typesafety all the way

Page 81: Javaland 2014 / GWT architectures and lessons learned

!

command pattern

GOF Pattern !

commonly used in Rich Clients

!

Page 82: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandlerEXECUTE

Page 83: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandlerPOJOS

Page 84: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandler

GWT-RPC

client server

batching caching security

caching exception translation security

GWT client

Page 85: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandler

RMI / HTTPInvoker

client server

batching caching security

caching exception translation security

Java client

Page 86: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandler

JSON-servlet

client server

batching caching security

caching exception translation security

Mobile client

Page 87: Javaland 2014 / GWT architectures and lessons learned

public class TerminLoadAction implements Action<DataResult<TerminData>> { ! private String terminId; ! public TerminLoadAction(String terminId) { this.terminId = terminId; } ! public String getTerminId() { return terminId; } }

public class DataResult<DATA extends Data> implements Result { ! private DATA data; ! public DataResult(DATA data) { this.data = data; } ! public void setData(DATA data) { this.data = data; } ! public DATA getData() { return data; } !}

aka DTOs

Action Result

Reusable

type safety

Page 88: Javaland 2014 / GWT architectures and lessons learned

dispatch.execute( ! new TerminLoadAction(terminId), new AsyncCallback<DataResult<TerminData>>() { ! @Override public void onFailure(Throwable caught) { } ! @Override public void onSuccess(DataResult<TerminData> result) { } ! } !);

<A extends Action<R>, R extends Result> void execute(A action, AsyncCallback<R> callback)

Page 89: Javaland 2014 / GWT architectures and lessons learned

public interface ActionHandler <A extends Action<R>, R extends Result> { ! Class<A> getActionType(); !!!! R execute( A action, ExecutionContext context) throws DispatchException; !}

Server sidetype safety

againhandler to action

mapping

action execution

declared exception hiearchy

Execution context for server side command execution

Page 90: Javaland 2014 / GWT architectures and lessons learned

@ActionHandlerBean @Transactional public final class TerminDataLoadHandler implements ActionHandler<TerminLoadAction, DataResult<TerminData>> { ! @Autowired private TerminDAO terminDao; ! @Override public DataResult<TerminData> execute( TerminLoadAction action, ExecutionContext context) throws DispatchException { ! TerminBean termin = … ! TerminData data = … ! return new DataResult<TerminData>(data); ! } ! @Override public Class<TerminLoadAction> getActionType() { return TerminLoadAction.class; } !}

Server side

custom annotationspring

access to backend

type safe result business logic, etc…

Page 91: Javaland 2014 / GWT architectures and lessons learned

interface versioning

hell?

Page 92: Javaland 2014 / GWT architectures and lessons learned

public interface SomeNiceService extends RemoteService { ! String someService(String param); ! String someServiceV2(String param); ! String someServiceV3(String param); }

public interface SomeNiceService extends RemoteService { ! String someService(String param); !} !public interface SomeNiceServiceV2 extends RemoteService { ! String someService(String param); !} !public interface SomeNiceServiceV3 extends RemoteService { ! String someService(String param); !}

easy way right way?

maintainability?maintainability?

Page 93: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandlerPOJOS

Page 94: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandlermultiple versions

someActionV2

someActionHandlerV2

same result

different versions can coexist!

Page 95: Javaland 2014 / GWT architectures and lessons learned

someAction

someResult

someActionHandlermultiple versions

someActionV2

someActionHandlerV2

someResultV2

different results

Page 96: Javaland 2014 / GWT architectures and lessons learned

why batch?

Page 97: Javaland 2014 / GWT architectures and lessons learned

solving common problems• one batch call is better than 10

single calls

• less data

• less roundtrip latency

• avoid connection bottleneck

• ensure server side execution order

• less roundtrips

Page 98: Javaland 2014 / GWT architectures and lessons learned

batchAction

someAction1

batchActionHandler

someAction2

someAction3

batchResult

someResult1

someResult2

someResult3

client server

batching can be manual or

automatic

server executes actions in given order

someAction1

someAction2

someAction3

Page 99: Javaland 2014 / GWT architectures and lessons learned

automatic batching?

Page 100: Javaland 2014 / GWT architectures and lessons learned

GWT code execution

IDLE

browser event loop

Scheduler.scheduleEntry(…)

Scheduler.scheduleFinally(…)

Scheduler.scheduleDeferred(…)

Page 101: Javaland 2014 / GWT architectures and lessons learned

GWT code execution

IDLE

Scheduler.scheduleEntry(…)

Scheduler.scheduleFinally(…)

Page 102: Javaland 2014 / GWT architectures and lessons learned

GWT code execution

IDLE

Scheduler.scheduleFinally(…)

collect commands

fire batch command

cmd 1!cmd 2!cmd 3!cmd …

Scheduler.scheduleEntry(…)

Page 103: Javaland 2014 / GWT architectures and lessons learned

ENABLES FINE GRAINED COMMANDS AND REUSE

!

+ !

ENABLES ORDERING ACTIONS FOR EXECUTION ON THE

SERVER

BATCH EXECUTION

Page 104: Javaland 2014 / GWT architectures and lessons learned

toggleTerminMetadata

reloadDashboardTermine

BooleanResult

DataListResult<Termin>

Page 105: Javaland 2014 / GWT architectures and lessons learned

toggleTerminMetadata

reloadTermin

BooleanResult

DataResult<Termin>

Page 106: Javaland 2014 / GWT architectures and lessons learned

toggleTerminMetadata

loadMonthStats

BooleanResult

DataResult<MonthStats>

loadMonthTermine DataListResult<Termin>

Page 107: Javaland 2014 / GWT architectures and lessons learned

Thanks!