Brett,
We did code splitting across the four major sections of our applications.
Assume we have section A-D, each with their own mediator. We then have an
ApplicationMediator, which is responsible for loading / unloading the four
major sections and sticking them into the viewport. When ApplicationMediator
receives a notification to load A, for example, it calls a method loadA()
that constructs the AMediator, gets its view component, and sticks it in the
viewport. The trick is that loadA() is wrapped in a runAsyc() block and
nowhere else do we ever construct an AMediator or even reference it, since
communication is all through notifications. You could certainly do the same
thing with a LoadACommand(). We just felt that since the command would have
to work intimately with ApplicationMediator, it's best to just stick the
logic in there.

Our history management is pretty intense as our app is quite large and
requires maintaining quite a bit of state (searches with up to 20-30
criteria). But, we did basically what you suggested. A HistoryManger class
is responsible for serializing and deserializing history state. The rest of
the application registers a certain token (say, "search"), providing a
serializer and a Command. When it a history event is fired for that token,
the entire state is serialized using the provided serializer then passed as
an argument to the command. This works really well, because if you have a
PerformSearch command that takes a SearchRequest as the body, it can be used
for the history mechanism AND through normal user actions. The only bit
about this I don't like, is that we use the third type parameter to signify
whether the command is being called as a result of a user action or a
history state change. If it's a user action, the command calls
HistoryManager, allowing it to do it's History.addToken call. It's a bit
hackish, but works.

Hope that makes sense.

- Amir

On Wed, Aug 19, 2009 at 9:43 PM, brett.wooldridge <
brett.wooldri...@gmail.com> wrote:

>
> Amir,
>
> After your post, I have been investigating PureMVC a bit.  Since you
> used it, I have a question.  In PureMVC, in the typical
> ApplicationFacade class there is an initializeController() override
> which registers all the commands.  How does this fit with code-
> splitting?  Currently our application is not PureMVC, and we highly
> leverage the new code-splitting features of GWT.  Do you leverage code-
> splitting?  If so, did you just register all the commands up front,
> but then in the execute() of the commands use runAsync() to allow
> splitting?  Where are the best points to apply runAsync() in the
> PureMVC architecture?
>
> Also, while I have your attention, how did you (or did you) fit
> browser history into the PureMVC model?  Did some sort of "history
> management" class receive notifications from the framework and manage
> history that way?  Did that class post notifications into the PureMVC
> framework in response to back/forward navigation?
>
> Thanks.
>
> On Aug 14, 6:36 am, Amir Kashani <amirkash...@gmail.com> wrote:
> > For my last work project, we used Kiyaa!, a GWT library that offers its
> own
> > declarative UI system (and data-binding). In addition, we used PureMVC as
> a
> > very lightweight MVC-framework. If you're familiar with PureMVC, you'll
> know
> > that it's much closer to MVP, as described by Ray Ryan, than it is a
> > traditional MVC framework. They worked beautifully together. Here's our
> > basic setup:
> >
> >    - *Views *- these are the plain UI components represented with Kyiaa!
> >    templates. They're smart enough to display Model data and handle any
> UI
> >    interactions, but delegate all business logic to their Mediators. They
> have
> >    a Listener interface that is implemented by the Mediator, which has
> >    "high-level" callback methods, such as onRegister, onNewCustomer, etc
> rather
> >    than onClick.
> >    - *Mediator *- responsible for "managing" the views by facilitating
> >    communication between the View and the rest of the system. They send
> and
> >    receive Notifications that are handled by other Mediators or by
> Commands.
> >    More specifically, they provide model data to the View as it's
> available and
> >    handle user-triggered events from the view, etc. The mediators have NO
> >    references to any Widgets or other UI components. Their only
> interaction
> >    with the View is from callbacks through the defined interface and
> through
> >    the View's public API, which is generally fairly-high level as well.
> Because
> >    of this, it's easy to re-use UI components by having a different
> Mediator
> >    controlling the UI.
> >
> >    - *Model* - these are your basic domain objects. They should be POJOs
> and
> >    have no concept of the rest of the system. Period.
> >    - *Proxy* - a Proxy's basic role is to provide a high-level API for
> >    managing the Model. Depending on the complexity of your domain object,
> it
> >    could be as simple as having methods such as addUser, deleteUser, etc.
> Or,
> >    for complex Models, such as a Word Document object, can have methods
> such as
> >    setTitle(), etc.
> >
> > In our setup, Proxys take the former role, basically encapsulating all
> RPC
> > logic, implementing client-side caching, etc. You call methods on a
> Proxy,
> > such as saveUser, and it sends Notifications to the rest of the system
> when
> > something interesting happens. Proxy's NEVER receive notifications,
> however.
> > They are not interested in the rest of the system, including the UI (or
> even
> > that there is a UI), and theoretically, along with the models, should
> > function completely on their own, making them highly reusable.
> >
> >    - *Command* - a Command is a place where you encode complex
> interactions.
> >    For example, if your application has a search function, you may have a
> >    SearchCommand that
> >       1. Receives the search query
> >       2. Calls the appropriate Proxy to do the RPC hit
> >       3. Loads the Mediator that will be interested in the Proxy's
> response,
> >       if not already loaded
> >
> > The SearchCommand would be triggered by a notification sent from some
> > Mediator. The idea is to stick the logic into a re-usable Command rather
> > than encoding it into a Mediator directly, as it may be needed from
> multiple
> > places.
> >
> > The great part about this design and MVP is, that if we want to switch to
> > UIBinder, all we have to do is modify the View classes. No other part of
> the
> > system would have to change one-bit.
> >
> > Another quick note on PureMVC: it's kind of a disservice to it to call it
> an
> > MVC framework, as there's very little code involved in the "framework".
> > Rather, it's a set of concepts and principles that have been very well
> > defined, that if followed correctly, lead to highly-reusable and easily
> > testable components. Even if you don't use the framework, I highly
> recommend
> > reading their best practices:
> http://puremvc.org/component/option,com_wrapper/Itemid,174/
> >
> > - Amir
> >
> > On Thu, Aug 13, 2009 at 2:27 AM, Andrés Testi <andres.a.te...@gmail.com
> >wrote:
> >
> >
> >
> >
> >
> > > How the UiBinder fits in the MVP architecture proposed at the google I/
> > > O talks? (http://code.google.com/intl/es-AR/events/io/sessions/
> > > GoogleWebToolkitBestPractices.html)
> > > Regards.
> >
> > > - Andrés
> >
>

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to