2009-08-05 10 views
25

Właśnie rozpocząłem nowy projekt GWT dla klienta i chciałbym poznać doświadczenia ludzi z różnymi architekturami GWT MVC. W ostatnim projekcie użyłem zarówno GXT MVC, jak i niestandardowego rozwiązania do przesyłania wiadomości (na podstawie Appcelerator's MQ). GXT MVC działało dobrze, ale wydawało się, że jest to przesada dla GWT i ciężko było pracować z historią przeglądarki. Słyszałem o PureMVC i GWTiger, ale nigdy z nich nie korzystałem. Nasze niestandardowe rozwiązanie MQ działało całkiem dobrze, ale utrudniło testowanie komponentów za pomocą JUnit.Jakie są Twoje zalecenia dotyczące projektowania aplikacji GWT? MVC, MVP czy niestandardowe rozwiązanie do przesyłania wiadomości?

Co więcej, słyszałem, że Google Wave (aplikacja GWT) jest napisana przy użyciu wzorca widoku modelu. Niedawno opublikowano numer sample MVP application, ale patrząc na kod, nie wydaje się on tak intuicyjny.

Jeśli tworzyłeś nową aplikację GWT, jakiej architektury używałbyś? Jakie są twoje wady i zalety?

Dzięki,

Matt

Odpowiedz

11

Cieszę to pytanie zostało zadane, ponieważ GWT desperatley potrzebuje Rails jak sposób strukturyzacji aplikacji. Proste podejście oparte na najlepszych praktykach, które będą działać dla 90% wszystkich przypadków użycia i umożliwia bardzo łatwą testowalność.

W ostatnich latach korzystałem z własnej implementacji MVP z bardzo pasywnym poglądem, który zniewalałby się tym, co prezenter każe mu zrobić.

Moje rozwiązanie składało się z następujących elementów:

  • interfejs za widget zdefiniowanie metod kontrolowania wizualnego wyglądu
  • klasę wykonawczą, która może być złożona lub użyć zewnętrznego biblioteki widget
  • Central Presenter dla ekranu zawierającego widoki N składające się z widgetów M
  • centralny model na ekranie, który przechowuje dane powiązane z bieżącym wyglądem wizualnym
  • Ogólne klasy nasłuchujące, takie jak "SourcesAddEvents [CustomerDTO]" (edytor nie lubi prawdziwych symboli generycznych java tutaj, więc użyłem nawiasów thoe), ponieważ w przeciwnym razie będziesz miał wiele takich samych interfejsów, które różnią się tylko typem

Widoki otrzymują odniesienie do prezentera jako jego parametru konstruktora, dzięki czemu mogą zainicjować swoje zdarzenia z prezenterem. Prezenter zajmie się tymi zdarzeniami i powiadomi inne widżety/widoki i lub zadzwoni do gwt-rpc, że na sukces umieści swój wynik w modelu. Model ma typowy mechanizm "List [String [String]] names = ....", który jest zarejestrowany w prezencie, dzięki czemu aktualizacja modelu przez żądanie gwt-rpc przechodzi do wszystkich widoków/widżetów, które są zainteresowani.

Dzięki tej aplikacji uzyskałem bardzo łatwą testowalność z EasyMock dla moich AsynInterfaces. Miałem również możliwość łatwej wymiany implementacji widoku/widżetu, ponieważ wszystko, co musiałem przerobić, to kod, który powiadomił prezentera o jakimś wydarzeniu - niezależnie od ukrytego widgetu (Button, Links, itp.).

Problemy z mojego podejścia:

  • Moja obecna realizacja sprawia, że ​​trudno, aby zsynchronizować dane wartości współczynnika pomiędzy centralnymi modeli różnych ekranach. Załóżmy, że masz ekran wyświetlający zestaw kategorii i kolejny ekran, na którym możesz dodawać/edytować te elementy. Obecnie bardzo trudno jest propagować te zdarzenia zmianowe poza granice ekranów, ponieważ wartości są buforowane w tych modelach i ciężko jest nam znaleźć, czy niektóre rzeczy są brudne (byłoby to łatwe w tradycyjnym web1.0-html -drogowy typ scenariusza z pamięcią podręczną deklarowaną przez serwer).
  • Parametry konstruktora widoków umożliwiają super łatwe testowanie, ale bez solidnej struktury Dependency-Injection, jeden będzie zawierał trochę kodu fabrycznego/instalacji UGLY wewnątrz "onModuleLoad()". W momencie, kiedy to zaczynałem, nie wiedziałem o Google GIN, więc kiedy zmienię swoją aplikację, wykorzystam to, aby pozbyć się tej tablicy. Ciekawym przykładem jest gra "HigherLower" w GIN-Trunk.
  • Po raz pierwszy historia nie była prawidłowa, więc trudno jest nawigować z jednej części aplikacji do drugiej. Moje podejście nie jest świadome historii, która jest poważnym kryzysem.

Moi Rozwiązania tych problemów:

  • Zastosowanie GIN usunąć boilerplate instalacyjny, który jest trudny do utrzymania
  • Podczas przechodzenia z GWT-EXT do GXT, wykorzystać swoje ramy MVC jako EventBus do dołączaj/odłączaj modularne ekrany, aby uniknąć problemów z buforowaniem/synchronizacją.
  • Pomyśl o jakimś "Miejscu" - tak jak Ray Ryan opisał w swoim przemówieniu na I/O 09, które łączy lukę między GXT-MVC a Podejście GWTs-Hitory
  • Zastosowanie MVP dla widżety wyizolować dostęp do danych

Podsumowanie:

nie sądzę, można użyć jednego podejścia „MVP” dla całej aplikacji. Zdecydowanie potrzebna jest historia dla aplikacji nawigacyjnej, eventbus taki jak GXT-MVC do podłączania/odłączania ekranów i MVP, aby umożliwić łatwe testowanie dostępu do danych dla widżetów.

Proponuję zatem podejście wielowarstwowe, które łączy w sobie te trzy elementy, ponieważ uważam, że "system jedno-event-mvp-system" nie będzie działał. Nawigacja/Załączanie ekranów/Dostęp do danych to trzy oddzielne kwestie, a w następnych miesiącach zmienię swoją aplikację (przejdę na GXT), aby wykorzystać wszystkie trzy ramy zdarzeń dla każdej sprawy osobno (najlepsze narzędzie do pracy). Wszystkie trzy elementy nie muszą być świadome siebie nawzajem. Wiem, że moje rozwiązanie dotyczy tylko projektów GXT.

Pisząc duże aplikacje GWT, czuję, że muszę wymyślić coś w rodzaju Spring-MVC na kliencie, co naprawdę jest do bani, ponieważ potrzeba dużo czasu i energii, by wypluć coś eleganckiego jak Spring MVC. GWT potrzebuje ramy aplikacji o wiele bardziej niż te małe, małe optymalizacje JS, na które tak ciężko pracują kompilatorzy.

+0

Ale te niewielkie małe optymalizacje JS są tym, co sprawia, że ​​GWT jest tak szybkie - i jest podstawową platformą dla bardziej wyrafinowanych frameworków, które, jeśli są wykonane prawidłowo, mogą zapewnić wszystkie korzyści abstrakcji bez ponoszenia kosztów wielu głębokich funkcji alls/depesz (GWT zoptymalizuje/rozwinie je). – Chii

+0

Szczególnie w przypadku dzielenia kodu w 2.0, GWT jest wystarczająco szybki dla twórcy IMO. Nie zrozumcie mnie źle, nie chcę zlekceważyć znaczenia tych optymalizacji. Ale deweloperzy napotykają problemy w świecie rzeczywistym i przydałyby się o wiele więcej dzięki tradycyjnemu sposobowi działania - w ramach aplikacji - teraz. – Sakuraba

+0

Sakuraba - Zgadzam się z Tobą, że GWT potrzebuje jakiegoś mechanizmu konwergencji konwencji do zorganizowania kodu. Nie obchodzi mnie, czy to się nazywa MVC czy MVP, po prostu chcę czegoś prostego i łatwego w użyciu. Użyłem GXT MVC [1] i, biały działa, może być mylące używać podczas wdrażania historii. Dla mnie historia jest jednym z najważniejszych aspektów aplikacji GWT i odkryłem, że najłatwiej jest ją wdrożyć wcześnie, niż później. Pochylam się do MVP b/c Google poleca (patrz odpowiedź JP poniżej). [1] http://raibledesigns.com/rd/entry/gxt_s_mvc_framework –

7

Oto najnowsza prezentacja Google IO pod numerem architecting your GWT application.

Ciesz się.

-JP

+0

także z google io 2009: Voices That matter: GWT - Architecture Best Practices: http://www.youtube.com/watch?v=Uwp3EVU5ePA –

1

Trzeba spojrzeć na GWT Portlets.Opracowaliśmy GWT Portlets Framework podczas pracy nad dużą aplikacją portalu HR, która jest teraz darmowa i open source. Ze strony Portlety GWT (hostowane pod kodem Google):

Model programowania przypomina nieco pisanie portletów JSR168 dla serwera portalu (Liferay, portal JBoss itp.). "Portal" to twoja aplikacja zbudowana za pomocą struktury portletów GWT jako biblioteki. Funkcjonalność aplikacji opracowywana jest jako luźno powiązane portlety, każdy z opcjonalnym serwerem DataProvider po stronie serwera.

Każdy Portlet umie uzewnętrznić swój stan w serializable podklasy PortletFactory (momento/DTO/fabryka wzorzec) podejmowaniu ważnych funkcji możliwe:

  • operacje CRUD są obsługiwane przez jednego GWT RPC dla wszystkich portletów
  • Układ portletów na "stronie" może być reprezentowany jako drzewo WidgetFactory (interfejs zaimplementowany przez PortletFactory).
  • Drzewa WidgetFactory można serializować i przekazywać do/od XML na serwerze, do przechowywania układów GUI (lub "strony") w plikach stron XML

Inne ważne cechy ram są wymienione poniżej:

  • Strony mogą być edytowane w przeglądarce przy starcie (przez deweloperów i/lub użytkowników) przy użyciu edytora układu ramy
  • Portlets są umieszczone absolutnie więc można używać przewijanie regionów
  • Portlets są konfigurowalne, wskazują, kiedy są one zajęte do automatycznego załadunku loading „spinner” wyświetlacz i można maksymalizować
  • tematycznie widżety w tym oknie dialogowym stylu CSS chlewie wymiana przycisków led, małe przyciski narzędzi i menu z szablonem HTML

Portlety GWT są zaimplementowane w kodzie Java i nie owijają żadnych zewnętrznych bibliotek JavaScript. Nie narzuca się żadnej struktury po stronie serwera (na przykład Spring lub J2EE), ale jest zaprojektowany tak, aby działał dobrze w połączeniu z takimi frameworkami.

3

Jeśli interesuje Cię korzystanie z architektury MVP, możesz rzucić okiem na GWTP: http://code.google.com/p/gwt-platform/. Jest to środowisko open source MVP, nad którym pracuję, obsługujące wiele fajnych funkcji GWT, w tym dzielenie kodu i zarządzanie historią, za pomocą prostego API opartego na adnotacjach. Jest całkiem nowy, ale jest już wykorzystywany w wielu projektach.

Powiązane problemy