SlideShare ist ein Scribd-Unternehmen logo
Florian Felberbauer | Cenarion
MVP mit dem Google Web Toolkit
• Enterprise-Applikationen
• Versicherungsbranche
• Java
• 5 Jahre GWT
2
MVP
3
M
V
P
aking
acation
lans
?
MVP
4
M
V
P
odel
iew
resenter
!
Ablauf
• Das Prinzip von MVP
• MVP mit GWT
• Activities/Places
• Testing
5
• 1996 von Mike Potel
• Verwandt mit MVC
• Ziele
– Verantwortlichkeiten trennen
– Flexibilität von UIs bei Änderungen des
Models erhöhen
– Testbarkeit der Applikationslogik
Model View Presenter
6
7
Model
Presenter
View
MVC - MVP
Model
Controller View
Von MVC zu MVP
UI
Wie interagieren User
mit dem UI?
Daten
Wie verwalte ich meine
Daten?
8
Daten
Wie sehen die Daten aus?
9
• RDMS
• NoSQL
• Service
• …
Daten
Wie sehen die Daten aus?
Wie werden die Daten spezifiziert?
10
Selektionen der Daten
• z.B. Filterung nach ID, Berechtigungen, …
• oder Darstellung derselben Daten in versch. Kontext
Daten
Wie sehen die Daten aus?
Wie werden die Daten spezifiziert?
Wie werden die Daten modifiziert?
11
• Änderung der Daten auf Selektionen: Insert, Update, …
UI
Wie werden Daten dargestellt?
12
• Welche Widgets werden benützt?
• Wie sehen versch. Views für versch. Benutzergruppen aus?
UI
Wie werden Daten dargestellt?
Wie verändern Events die Daten?
13
• Datenänderung durch Events (Klick, Drag&Drop, …)
UI
Wie werden Daten dargestellt?
Wie verändern Events die Daten?
Wie fügt man alles zusammen?
14
= Presenter – Businesslogik verbindet Daten und UI
Kapselung der Applikation in Client und
Server
Security
15
Kapselung der Applikation in Client und
Server
Security
16
!Client untrustable! Security zumindest auf Serverseite
Vorteile von MVP
• Trennung von Model und View
→ mehr Flexibilität
• Ein Model – mehrere Views
• Skalierbarkeit
• Testbarkeit
17
MVP in GWT
18
Server
Client
Model
Presenter
View
Datenanbindung,
Businesstransaktionen
UI-Widgets, I18n,
Event-Handling, Display-Logik
View mit Daten füttern,
Applikationslogik
Display-Logik vs.
Applikationslogik
19
Unit-Test → Applikationslogik
Warum MVP in GWT?
• Arbeitsteilung
– Lose Kopplung UI – Logik
– Struktur erleichtert Orientierung
• Testbarkeit
20
Warum MVP in GWT?
• Arbeitsteilung
• Testbarkeit
21
Warum MVP in GWT?
• Arbeitsteilung
• Testbarkeit
– UI-Komponenten in GWT:
• Schwer testbar (GWT-Eigenheiten wie
GWT.create())
• Tests langsam
22
Warum MVP in GWT?
• Arbeitsteilung
• Testbarkeit
– UI-Komponenten in GWT:
• Schwer testbar
• Tests langsam (HTMLUnit, native JS)
23
Warum MVP in GWT?
• Arbeitsteilung
• Testbarkeit
– UI-Komponenten in GWT:
• Schwer testbar
• Tests langsam
– Abgrenzung Applikations-Logik von
Display-Logik!
24
Activities & Places
• Browser-History
• URL-Fragment = Place
– .../index.html#SearchPlace!bmw!pkw
• Place repräsentiert State
• Activity
– Kommunikation mit Serverseite
– Daten laden & UI initialisieren
25
State
26
Place Session
Primitive Werte
Objekt-Ids
Authentifizierung
Sprache
Presenter = Activity
Presenter
(Activity)
Place
View
hält State für
initialisiert
Model kommuniziert mit
27
aktualisiert
UiBinder
28
• Trennung Markup und Displaylogik
• Reines Markup in XML File
• Wird in HTML übersetzt
• Code in Java-Klasse
• Compile-time checking von Referenzen
Beispiel: Suche
29
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:Label text="Suche nach beschädigtem Fahrzeug" />
<g:Label text="Fahrgestell-Nr." />
<g:TextBox ui:field="vehicleId" />
<g:Label text="Marke" />
<g:TextBox ui:field="brand" />
<g:Label text="Fahrzeugtyp"/>
<g:ListBox ui:field="type" />
<g:Button text="OK“ ui:field="btnOk" />
<g:Button text="Zurücksetzen" />
</ui:UiBinder>
30
Beispiel: SearchViewImpl.ui.xml
 <input type="text" … />
 <input type="text" … />
 <select…><option>…
 <input type="button" … />
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:Label text="Suche nach beschädigtem Fahrzeug" />
<g:Label text="Fahrgestell-Nr." />
<g:TextBox ui:field="vehicleId" />
<g:Label text="Marke" />
<g:TextBox ui:field="brand" />
<g:Label text="Fahrzeugtyp"/>
<g:ListBox ui:field="type" />
<g:Button text="OK“ ui:field="btnOk" />
<g:Button text="Zurücksetzen" />
<g:Label ui:field="errorText" />
</ui:UiBinder>
31
Beispiel: SearchViewImpl.ui.xml
 <input type="text" … />
 <input type="text" … />
 <select…><option>…
 <input type="button" … />
Beispiel: SearchViewImpl
public class SearchViewImpl extends Composite {
/** View enthält nur EventHandling,
keine Applikationslogik */
@UiField TextBox vehicleId, brand;
@UiField ListBox type;
@UiField Label errorText;
private SearchPresenter presenter;
@UiHandler("btnOk")
public void onOkClick(ClickEvent event) {
presenter.searchOkClicked(); //delegate to presenter
}
}
32
Beispiel: Presenter
private DamagedVehicleRequest request;
private SearchView view;
public void searchOkClicked() {
if (!validVehicleId(view.getVin())) {
view.setErrorText("Fehlermeldung");
} else {
request.search(view.getVin(), view.getBrand(), view.getType())
.fire(new Receiver …);
}
}
33
Klassen/Dateien
34
SearchPlace
SearchView.ui.xml
UiBinder
Place
AbstractActivity
ActivityMapper
Composite
Lookup / Dependency Injection
SearchPresenter
SearchView
Interfaces?
35
SearchPresenter
SearchView
ISearchPresenter
ISearchView
Testbarkeit?
36
private DamagedVehicleRequest request;
private SearchView view;
public void searchOkClicked() {
if (!validVehicleId(view.getVin())) {
view.setErrorText("Fehlermeldung");
} else {
request.search(view.getVin(), view.getBrand(), view.getType())
.fire(new Receiver …);
}
}
Beispiel: Presenter
37
Beispiel: Presenter-Test
//Mocking der Serverkommunikation
private final Request<DamagedVehicleProxy> requestMock =
mock(Request.class);
private DamagedVehicleRequest requestContextMock;
private SearchPresenter presenter;
//Mocking des View-Interfaces
private SearchView viewMock;
38
Beispiel: Presenter-Test
@Before
public void setup() {
viewMock = Mockito.mock(SearchView.class); //Interface!
requestContextMock = Mockito.mock(DamagedVehicleRequest.class);
presenter = new SearchPresenter(view, request);
}
39
Beispiel: Presenter-Test
@Test
public void testSearchValid() {
Mockito.when(viewMock.getVehicleId()).thenReturn(null);
Mockito.when(requestMock.search(null, null, null))
.thenReturn(requestMock);
presenter.searchOkClicked();
Mockito.verify(requestContextMock)
.search(Mockito.eq((String)null), Mockito.anyString(),
Mockito.anyString());
}
40
Beispiel: Presenter-Test
@Test
public void testSearchInvalid() {
Mockito.when(viewMock.getVehicleId()).thenReturn("1");
presenter.searchOkClicked();
Mockito.verify(viewMock).setErrorText("Fehlermeldung");
Mockito.verifyZeroInteractions(requestContextMock);
}
41
Referenzen
44
Cenarion Techblog – Erfahrungen mit GWT, Tipps & Tricks
http://www.cenarion.com/techblog
View-Tests in GWT: http://www.objectpartners.com/2013/11/07/testing-gwt-
with-gwtmockito/
GWT SDK inkl. einiger Beispielprojekte
http://www.gwtproject.org/download.html
Real-World Projects:
http://www.gwtproject.org/examples.html#real-world-projects
What is the best way to test gwt code:
http://stackoverflow.com/questions/411257/what-is-the-best-way-to-test-gwt-
code
florian.felberbauer@cenarion.com
http://www.cenarion.com/techblog
45

Weitere ähnliche Inhalte

PDF
Eintauchen in MVP mit GWT
PDF
GWT: Eintauchen in MVP und Internationalisierung
PDF
GWT – Google Web Toolkit in der Praxis
PPTX
JavaServer Faces 2.2 (Herbstcampus 2013)
PDF
JSF meets JS (2. ed.) - JSF-Komponenten mit JavaScript
PDF
Metadatenbasierte Validierung
PPTX
Go Fullstack: Webanwendungen mit Java EE 6 bauen (W-JAX 2011)
PPTX
JSF und JPA effizient kombinieren (W-JAX 2011)
Eintauchen in MVP mit GWT
GWT: Eintauchen in MVP und Internationalisierung
GWT – Google Web Toolkit in der Praxis
JavaServer Faces 2.2 (Herbstcampus 2013)
JSF meets JS (2. ed.) - JSF-Komponenten mit JavaScript
Metadatenbasierte Validierung
Go Fullstack: Webanwendungen mit Java EE 6 bauen (W-JAX 2011)
JSF und JPA effizient kombinieren (W-JAX 2011)

Was ist angesagt? (20)

PDF
WebGL - 3D im Browser - Erfahrungsbericht mit BabylonJS
PPTX
JSF 2 Kompositkomponenten (JAX 2012)
PDF
Vor- und Nachteile von Web Components mit Polymer gegenüber AngularJS ohne P...
PDF
Web Components
PDF
Grails im Überblick und in der Praxis
PDF
Web-GUIs mit Vaadin
PDF
Progressive Web Apps mit Angular
PDF
Java-Webanwendungen mit Vaadin 8
PDF
Feature Flags mit Togglz
PDF
PHP-Module in statischen Seiten - Architektur-Ansätze
PPTX
WPF Dos n Don'ts - der WPF Rundumschlag
PPTX
Wie viel Client braucht das Web?JSF, Vaadin und AngularJS im Vergleich
PDF
Wieviel Client braucht das Web?
PDF
Factory Method Design Pattern
PDF
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
PDF
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
PDF
MEAN SCS in der Cloud
PDF
CodeTalks Vortrag: Automatisierung mit Ansible & Jenkins @ LeanIX Enterprise ...
PDF
dotnet Cologne 2013 - Windows Azure Mobile Services
PPTX
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
WebGL - 3D im Browser - Erfahrungsbericht mit BabylonJS
JSF 2 Kompositkomponenten (JAX 2012)
Vor- und Nachteile von Web Components mit Polymer gegenüber AngularJS ohne P...
Web Components
Grails im Überblick und in der Praxis
Web-GUIs mit Vaadin
Progressive Web Apps mit Angular
Java-Webanwendungen mit Vaadin 8
Feature Flags mit Togglz
PHP-Module in statischen Seiten - Architektur-Ansätze
WPF Dos n Don'ts - der WPF Rundumschlag
Wie viel Client braucht das Web?JSF, Vaadin und AngularJS im Vergleich
Wieviel Client braucht das Web?
Factory Method Design Pattern
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schnelle Winkel: 10x schnellere Webapps mit AngularJS und JEE
MEAN SCS in der Cloud
CodeTalks Vortrag: Automatisierung mit Ansible & Jenkins @ LeanIX Enterprise ...
dotnet Cologne 2013 - Windows Azure Mobile Services
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Anzeige

Ähnlich wie MVP mit dem Google Web Toolkit (20)

PPTX
2007 - Basta!: Nach soa kommt soc
PPTX
Google Analytics Konferenz 2016: Google Analytics Premium im Überblick (Micha...
PDF
Google Analytics Konferenz 2015: WORKSHOP: Enhanced ECommerce (Michaela Linha...
PPTX
Anatomie von AdWords Scripts - Einführung
PDF
Google Analytics Konferenz 2012: Thomas Tauchner, e-dialog: Events implementi...
PDF
SAP IdM Wartungsende 2027... und was nun?
PDF
Mobile Analytics - wie Sie Ihre mobilen Nutzer mit Google Analytics besser v...
PDF
Enterprise UI
PDF
Automatisierung von Client-seitigen Web-Performance-Optimierungen
PDF
Die Flux Application Architecture - Facebooks Ansatz für Client-side Web Appl...
PDF
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
PDF
SharePoint 2013: Die Neuerungen im Überblick
PDF
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
PDF
Anforderungsanalyse und UML Grundlagen
PDF
20150611 track4 2_ae21_salesforce and ibm software
PPTX
DNUG - Andreas Rosen - IBM Software und Salesforce sinnvoll integrieren
PPTX
Webvisor - kostenlose Analyse des Benutzerverhaltens
PDF
Reportings & Insights mit Google Data Studio | Google Analytics Konferenz 2019
PDF
Webvisor – kostenlose Analyse von Benutzerverhalten
PPTX
Conversion-Optimierung für Online-Shops - Jörg Dennis Krüger - iico2012
2007 - Basta!: Nach soa kommt soc
Google Analytics Konferenz 2016: Google Analytics Premium im Überblick (Micha...
Google Analytics Konferenz 2015: WORKSHOP: Enhanced ECommerce (Michaela Linha...
Anatomie von AdWords Scripts - Einführung
Google Analytics Konferenz 2012: Thomas Tauchner, e-dialog: Events implementi...
SAP IdM Wartungsende 2027... und was nun?
Mobile Analytics - wie Sie Ihre mobilen Nutzer mit Google Analytics besser v...
Enterprise UI
Automatisierung von Client-seitigen Web-Performance-Optimierungen
Die Flux Application Architecture - Facebooks Ansatz für Client-side Web Appl...
GAUC 2017 Workshop App Tracking: Markus Vollmert (lunapark)
SharePoint 2013: Die Neuerungen im Überblick
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
Anforderungsanalyse und UML Grundlagen
20150611 track4 2_ae21_salesforce and ibm software
DNUG - Andreas Rosen - IBM Software und Salesforce sinnvoll integrieren
Webvisor - kostenlose Analyse des Benutzerverhaltens
Reportings & Insights mit Google Data Studio | Google Analytics Konferenz 2019
Webvisor – kostenlose Analyse von Benutzerverhalten
Conversion-Optimierung für Online-Shops - Jörg Dennis Krüger - iico2012
Anzeige

MVP mit dem Google Web Toolkit

  • 1. Florian Felberbauer | Cenarion MVP mit dem Google Web Toolkit
  • 5. Ablauf • Das Prinzip von MVP • MVP mit GWT • Activities/Places • Testing 5
  • 6. • 1996 von Mike Potel • Verwandt mit MVC • Ziele – Verantwortlichkeiten trennen – Flexibilität von UIs bei Änderungen des Models erhöhen – Testbarkeit der Applikationslogik Model View Presenter 6
  • 8. Von MVC zu MVP UI Wie interagieren User mit dem UI? Daten Wie verwalte ich meine Daten? 8
  • 9. Daten Wie sehen die Daten aus? 9 • RDMS • NoSQL • Service • …
  • 10. Daten Wie sehen die Daten aus? Wie werden die Daten spezifiziert? 10 Selektionen der Daten • z.B. Filterung nach ID, Berechtigungen, … • oder Darstellung derselben Daten in versch. Kontext
  • 11. Daten Wie sehen die Daten aus? Wie werden die Daten spezifiziert? Wie werden die Daten modifiziert? 11 • Änderung der Daten auf Selektionen: Insert, Update, …
  • 12. UI Wie werden Daten dargestellt? 12 • Welche Widgets werden benützt? • Wie sehen versch. Views für versch. Benutzergruppen aus?
  • 13. UI Wie werden Daten dargestellt? Wie verändern Events die Daten? 13 • Datenänderung durch Events (Klick, Drag&Drop, …)
  • 14. UI Wie werden Daten dargestellt? Wie verändern Events die Daten? Wie fügt man alles zusammen? 14 = Presenter – Businesslogik verbindet Daten und UI
  • 15. Kapselung der Applikation in Client und Server Security 15
  • 16. Kapselung der Applikation in Client und Server Security 16 !Client untrustable! Security zumindest auf Serverseite
  • 17. Vorteile von MVP • Trennung von Model und View → mehr Flexibilität • Ein Model – mehrere Views • Skalierbarkeit • Testbarkeit 17
  • 18. MVP in GWT 18 Server Client Model Presenter View Datenanbindung, Businesstransaktionen UI-Widgets, I18n, Event-Handling, Display-Logik View mit Daten füttern, Applikationslogik
  • 20. Warum MVP in GWT? • Arbeitsteilung – Lose Kopplung UI – Logik – Struktur erleichtert Orientierung • Testbarkeit 20
  • 21. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit 21
  • 22. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar (GWT-Eigenheiten wie GWT.create()) • Tests langsam 22
  • 23. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar • Tests langsam (HTMLUnit, native JS) 23
  • 24. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar • Tests langsam – Abgrenzung Applikations-Logik von Display-Logik! 24
  • 25. Activities & Places • Browser-History • URL-Fragment = Place – .../index.html#SearchPlace!bmw!pkw • Place repräsentiert State • Activity – Kommunikation mit Serverseite – Daten laden & UI initialisieren 25
  • 27. Presenter = Activity Presenter (Activity) Place View hält State für initialisiert Model kommuniziert mit 27 aktualisiert
  • 28. UiBinder 28 • Trennung Markup und Displaylogik • Reines Markup in XML File • Wird in HTML übersetzt • Code in Java-Klasse • Compile-time checking von Referenzen
  • 30. <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <g:Label text="Suche nach beschädigtem Fahrzeug" /> <g:Label text="Fahrgestell-Nr." /> <g:TextBox ui:field="vehicleId" /> <g:Label text="Marke" /> <g:TextBox ui:field="brand" /> <g:Label text="Fahrzeugtyp"/> <g:ListBox ui:field="type" /> <g:Button text="OK“ ui:field="btnOk" /> <g:Button text="Zurücksetzen" /> </ui:UiBinder> 30 Beispiel: SearchViewImpl.ui.xml  <input type="text" … />  <input type="text" … />  <select…><option>…  <input type="button" … />
  • 31. <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <g:Label text="Suche nach beschädigtem Fahrzeug" /> <g:Label text="Fahrgestell-Nr." /> <g:TextBox ui:field="vehicleId" /> <g:Label text="Marke" /> <g:TextBox ui:field="brand" /> <g:Label text="Fahrzeugtyp"/> <g:ListBox ui:field="type" /> <g:Button text="OK“ ui:field="btnOk" /> <g:Button text="Zurücksetzen" /> <g:Label ui:field="errorText" /> </ui:UiBinder> 31 Beispiel: SearchViewImpl.ui.xml  <input type="text" … />  <input type="text" … />  <select…><option>…  <input type="button" … />
  • 32. Beispiel: SearchViewImpl public class SearchViewImpl extends Composite { /** View enthält nur EventHandling, keine Applikationslogik */ @UiField TextBox vehicleId, brand; @UiField ListBox type; @UiField Label errorText; private SearchPresenter presenter; @UiHandler("btnOk") public void onOkClick(ClickEvent event) { presenter.searchOkClicked(); //delegate to presenter } } 32
  • 33. Beispiel: Presenter private DamagedVehicleRequest request; private SearchView view; public void searchOkClicked() { if (!validVehicleId(view.getVin())) { view.setErrorText("Fehlermeldung"); } else { request.search(view.getVin(), view.getBrand(), view.getType()) .fire(new Receiver …); } } 33
  • 37. private DamagedVehicleRequest request; private SearchView view; public void searchOkClicked() { if (!validVehicleId(view.getVin())) { view.setErrorText("Fehlermeldung"); } else { request.search(view.getVin(), view.getBrand(), view.getType()) .fire(new Receiver …); } } Beispiel: Presenter 37
  • 38. Beispiel: Presenter-Test //Mocking der Serverkommunikation private final Request<DamagedVehicleProxy> requestMock = mock(Request.class); private DamagedVehicleRequest requestContextMock; private SearchPresenter presenter; //Mocking des View-Interfaces private SearchView viewMock; 38
  • 39. Beispiel: Presenter-Test @Before public void setup() { viewMock = Mockito.mock(SearchView.class); //Interface! requestContextMock = Mockito.mock(DamagedVehicleRequest.class); presenter = new SearchPresenter(view, request); } 39
  • 40. Beispiel: Presenter-Test @Test public void testSearchValid() { Mockito.when(viewMock.getVehicleId()).thenReturn(null); Mockito.when(requestMock.search(null, null, null)) .thenReturn(requestMock); presenter.searchOkClicked(); Mockito.verify(requestContextMock) .search(Mockito.eq((String)null), Mockito.anyString(), Mockito.anyString()); } 40
  • 41. Beispiel: Presenter-Test @Test public void testSearchInvalid() { Mockito.when(viewMock.getVehicleId()).thenReturn("1"); presenter.searchOkClicked(); Mockito.verify(viewMock).setErrorText("Fehlermeldung"); Mockito.verifyZeroInteractions(requestContextMock); } 41
  • 42. Referenzen 44 Cenarion Techblog – Erfahrungen mit GWT, Tipps & Tricks http://www.cenarion.com/techblog View-Tests in GWT: http://www.objectpartners.com/2013/11/07/testing-gwt- with-gwtmockito/ GWT SDK inkl. einiger Beispielprojekte http://www.gwtproject.org/download.html Real-World Projects: http://www.gwtproject.org/examples.html#real-world-projects What is the best way to test gwt code: http://stackoverflow.com/questions/411257/what-is-the-best-way-to-test-gwt- code