views:

3914

answers:

6

Hello,

I just started a new GWT project for a client and I'm interested in hearing people's experience with various GWT MVC architectures. On a recent project, I used both GXT MVC, as well as a custom messaging solution (based on Appcelerator's MQ). GXT MVC worked OK, but it seemed like overkill for GWT and was hard to make work with browser history. I've heard of PureMVC and GWTiger, but never used them. Our custom MQ solution worked pretty well, but made it difficult to test components with JUnit.

In addition, I've heard that Google Wave (a GWT application) is written using a Model-View-Presenter pattern. A sample MVP application was recently published, but looking at the code, it doesn't seem that intuitive.

If you were building a new GWT application, which architecture would you use? What are the pros and cons of your choice?

Thanks,

Matt

+9  A: 

I am glad this question has been asked, because GWT desperatley needs a rails-like way of structuring an application. A simple approach based on best practices that will work for 90 % of all use-cases and enables super easy testability.

In the past years I have been using my own implementation of MVP with a very passive view that enslaves itself to whatever the Presenter tells him to do.

My solution consisted of the following:

  • an interface per widget defining the methods to control the visual appearance
  • an implementing class that can be a Composite or use an external widget library
  • a central Presenter for a screen that hosts N views that are made up of M widgets
  • a central model per screen that holds the data associated with the current visual appearance
  • generic listener classes like "SourcesAddEvents[CustomerDTO]" (the editor does not like the real symbols for java generics here, so I used thoe brackets), because otherwise you will have lots of the same interfaces who just differ by the type

The Views get a reference to the presenter as their constructor parameter, so they can initialize their events with the presenter. The presenter will handles those events and notify other widgets/views and or call gwt-rpc that on success puts its result into the model. The model has a typical "Property[List[String]] names = ...." property change listener mechanism that is registered with the presenter so that the update of a model by an gwt-rpc request goes to all views/widgets that are interested.

With this appraoch I have gotten very easy testability with EasyMock for my AsynInterfaces. I also got the ability to easily exchange the implementation of a view/widget, because all I had to rewrite was the code that notified the presenter of some event - regardless of the underlying widget (Button, Links, etc).

Problems with my approach:

  • My current implementation makes it hard to synchronize data-values between the central models of different screens. Say you have a screen that displays a set of categories and another screen that lets you add/edit those items. Currently it is very hard to propagate those change events across the boundaries of the screens, because the values are cached in those models and it is hard to find our whether some things are dirty (would have been easy in a traditional web1.0-html-dumb-terminal kind of scenario with serverside declarative caching).
  • The constructor parameters of the views enable super-easy testing, but without a solid Dependency-Injection framework, one will have some UGLY factory/setup code inside "onModuleLoad()". At the time I started this, I was not aware of Google GIN, so when I refactor my app, I will use that to get rid of this boilerplate. An interesting example here is the "HigherLower" game inside the GIN-Trunk.
  • I did not get History right the first time, so it is hard to navigate from one part of my app to another. My approach is not aware of History, which is a serious downturn.

My Solutions to those problems:

  • Use GIN to remove the setup boilerplate that is hard to maintain
  • While moving from Gwt-Ext to GXT, use its MVC framework as an EventBus to attach/detach modular screens, to avoid the caching/synchronization issues
  • Think of some kind of "Place"-Abstraction like Ray Ryan described in his talk at I/O 09, which bridges the Event-Gap between GXT-MVC and GWTs-Hitory approach
  • Use MVP for widgets to isolate data access

Summary:

I dont think one can use a single "MVP" approach for an entire app. One definetly needs history for app-navigation, a eventbus like GXT-MVC to attach/detach screens, and MVP to enable easy testing of data access for widgets.

I therefore propose a layered approach that combines these three elements, since I believe that the "one-event-mvp-system"-solution wont work. Navigation/Screen-Attaching/Data-Access are three separate concerns and I will refactor my app (move to GXT) in the following months to utilize all three event-frameworks for each concerns separately (best tool for the job). All three elements need not be aware of each other. I do know that my solution only applies for GXT-projects.

When writing big GWT apps, I feel like I have to reinvent something like Spring-MVC on the client, which really sucks, because it takes a lot of time and brain-power to spit out something elegant as Spring MVC. GWT needs an app framework much more than those tiny little JS-optimizations that the compiler-guys work so hard on.

Sakuraba
But those tiny little JS-optimizations are what makes GWT so fast - and it is a base platform for more sophisticated frameworks which, if made properly, could provide all the benefits of abstraction without incurring the cost of lots of deep function alls/dispatches (GWT will optimize/inline them away).
Chii
Especially with Code-Splitting in 2.0, GWT is fast enough for the averge developer IMO. Dont get me wrong, I dont want to dismiss the importance of those optimizations. But developers face real-world-problems and would benefit a lot more from a conventional way of doings things - an application framework - right now.
Sakuraba
Sakuraba - I agree with you that GWT needs some sort of convention-over-configuration mechanism to organize code. I don't care if it's called MVC or MVP, I just want something that's simple and easy to use. I've used GXT MVC[1] and, white it works, it can be confusing to use when you implement history. To me, history is one of the most important aspects of a GWT application and I've found that it's easiest to implement early rather than bolt on afterward.I'm leaning toward MVP b/c Google recommends it (see JP's answer below). [1] http://raibledesigns.com/rd/entry/gxt_s_mvc_framework
Matt Raible
If their MVP demo includes multiple screen navigation, removing the current screen from the view, attaching another screen, etc, I am all for it. Unfortunately this has not materialized yet.
Sakuraba
+6  A: 

Here is a recent Google IO presentation on architecting your GWT application.

Enjoy.

-JP

JP
also from google io 2009: Voices That Matter: GWT - Architecture Best Practices: http://www.youtube.com/watch?v=Uwp3EVU5ePA
Ray Tayek
+1  A: 

You should have a look at GWT Portlets. We developed the GWT Portlets Framework while working on a large HR Portal application and it is now free and open source. From the GWT Portlets website (hosted on Google code):

The programming model is somewhat similar to writing JSR168 portlets for a portal server (Liferay, JBoss Portal etc.). The "portal" is your application built using the GWT Portlets framework as a library. Application functionality is developed as loosely coupled Portlets each with an optional server side DataProvider.

Every Portlet knows how to externalize its state into a serializable PortletFactory subclass (momento / DTO / factory pattern) making important functionality possible:

  • CRUD operations are handled by a single GWT RPC for all Portlets
  • The layout of Portlets on a "page" can be represented as a tree of WidgetFactory's (an interface implemented by PortletFactory)
  • Trees of WidgetFactory's can be serialized and marshalled to/from XML on the server, to store GUI layouts (or "pages") in XML page files

Other important features of the framework are listed below:

  • Pages can be edited in the browser at runtime (by developers and/or users) using the framework layout editor
  • Portlets are positioned absolutely so can use scrolling regions
  • Portlets are configurable, indicate when they are busy loading for automatic "loading spinner" display and can be maximized
  • Themed widgets including a styled dialog box, a CSS styled button replacement, small toolbuttons and a HTML template driven menu

GWT Portlets is implemented in Java code and does not wrap any external Javascript libraries. It does not impose any server side framework (e.g. Spring or J2EE) but is designed to work well in conjunction with such frameworks.

David Tinker
+2  A: 

Hello, everyone is interested in printable and readable version of Google IO, please look
http://extgwt-mvp4g-gae.blogspot.com/2009/10/gwt-app-architecture-best-practices.html

Araminos
+6  A: 

It's worth noting that google has finally written out a tutorial for designing using the mvp architecture. It clarifies a lot of the elements from the google i/o talk listed above. Take a looK: http://code.google.com/webtoolkit/doc/latest/tutorial/mvp-architecture.html

Dhruv
+2  A: 

If you're interested in using the MVP architecture, you might want to take a look at GWTP: http://code.google.com/p/gwt-platform/ . It's an open source MVP framework I'm working on, that supports many nice features of GWT, including code splitting and history management, with a simple annotation-based API. It is quite recent, but is already being used in a number of projects.

Philippe Beaudoin