MVP mit dem Google Web Toolkit

877 Aufrufe

Veröffentlicht am

Mit dem Google Web Toolkit (GWT) kann das Frontend einer Webapplikation bequem in Java entwickelt werden. Für die Steuerung des UIs wird von Google das Model-View-Presenter-Pattern (MVP) empfohlen.
Es schreibt eine strenge Trennung von View und Presenter vor, die zu einer sauberen Gliederung führt und der Testbarkeit dient. Wir zeigen, wie man MVP mit GWT einsetzt und dabei Unit-Tests zur Qualitätssicherung nutzt.
Activities und Places helfen in GWT-Applikationen die Browser-History zu verwenden. Wir zeigen, wie Activities und Places mit MVP zusammen spielen.

Veröffentlicht in: Technologie
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
877
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
384
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

MVP mit dem Google Web Toolkit

  1. 1. Florian Felberbauer | Cenarion MVP mit dem Google Web Toolkit
  2. 2. • Enterprise-Applikationen • Versicherungsbranche • Java • 5 Jahre GWT 2
  3. 3. MVP 3 M V P aking acation lans ?
  4. 4. MVP 4 M V P odel iew resenter !
  5. 5. Ablauf • Das Prinzip von MVP • MVP mit GWT • Activities/Places • Testing 5
  6. 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
  7. 7. 7 Model Presenter View MVC - MVP Model Controller View
  8. 8. Von MVC zu MVP UI Wie interagieren User mit dem UI? Daten Wie verwalte ich meine Daten? 8
  9. 9. Daten Wie sehen die Daten aus? 9 • RDMS • NoSQL • Service • …
  10. 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. 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. 12. UI Wie werden Daten dargestellt? 12 • Welche Widgets werden benützt? • Wie sehen versch. Views für versch. Benutzergruppen aus?
  13. 13. UI Wie werden Daten dargestellt? Wie verändern Events die Daten? 13 • Datenänderung durch Events (Klick, Drag&Drop, …)
  14. 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. 15. Kapselung der Applikation in Client und Server Security 15
  16. 16. Kapselung der Applikation in Client und Server Security 16 !Client untrustable! Security zumindest auf Serverseite
  17. 17. Vorteile von MVP • Trennung von Model und View → mehr Flexibilität • Ein Model – mehrere Views • Skalierbarkeit • Testbarkeit 17
  18. 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
  19. 19. Display-Logik vs. Applikationslogik 19 Unit-Test → Applikationslogik
  20. 20. Warum MVP in GWT? • Arbeitsteilung – Lose Kopplung UI – Logik – Struktur erleichtert Orientierung • Testbarkeit 20
  21. 21. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit 21
  22. 22. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar (GWT-Eigenheiten wie GWT.create()) • Tests langsam 22
  23. 23. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar • Tests langsam (HTMLUnit, native JS) 23
  24. 24. Warum MVP in GWT? • Arbeitsteilung • Testbarkeit – UI-Komponenten in GWT: • Schwer testbar • Tests langsam – Abgrenzung Applikations-Logik von Display-Logik! 24
  25. 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
  26. 26. State 26 Place Session Primitive Werte Objekt-Ids Authentifizierung Sprache
  27. 27. Presenter = Activity Presenter (Activity) Place View hält State für initialisiert Model kommuniziert mit 27 aktualisiert
  28. 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
  29. 29. Beispiel: Suche 29
  30. 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. 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. 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. 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
  34. 34. Klassen/Dateien 34 SearchPlace SearchView.ui.xml UiBinder Place AbstractActivity ActivityMapper Composite Lookup / Dependency Injection SearchPresenter SearchView
  35. 35. Interfaces? 35 SearchPresenter SearchView ISearchPresenter ISearchView
  36. 36. Testbarkeit? 36
  37. 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. 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. 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. 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. 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. 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
  43. 43. florian.felberbauer@cenarion.com http://www.cenarion.com/techblog 45

×