What's your recommendation for architecting GWT applications? MVC, MVP or custom messaging solution?

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-29 21:07:48
Dhruv

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: https://developers.google.com/web-toolkit/articles/mvp-architecture

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.

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

Enjoy.

-JP

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!