HMVC Pattern For GWT & Swing Applications In Java

Why Pattern?

When developing client tier of application using html,  there are certain limitations in the way we can organize the things. Because the code is in XML. Religious java developers are generally seen more inclined towards GWT rather than HTML. Because it keeps them in their comfort zone :) . More importantly, you get power of OOPs in Java. You can apply different sorts of pattern to organize your UI components and keep your code decoupled – which becomes very difficult if it was to be done in javascript. However, this organization of UI code and its interaction with server side components sounds easier than it is in practice. We will see an emerging HMVC Pattern for GWT and Swing based application.

HMVC Pattern (Hierarchical Model View Controller) Introduced:

HMVC Pattern can be seen as extended version of MVC pattern. We can divide our GUI into different GUI objects some of which will be for navigation purpose (Menubar), some for displaying/editing data(Grid/Tree/Forms) and others may be use for just layouting purpose. So we clearly identify three major aspect of GUI objects.

  1. Layouting – It is taken care by View in HMVC.
  2. Handling user interactions – Its Controller‘s responsibility.
  3. Server Interactions And Hold Data Being Displayed – Model handles this.

In HMVC Pattern, we assign dedicated Controller and Model for each of these objects. It is not necessary to provide each of the GUI object its own controller and model. To keep it simple, we can give dedicated controllers and models only to all the Pages, Grid, Dynamic Tree and other major navigation areas e.g. ContentPanel.

Getting In Depth Of HMVC: In MVC architecture, View can only interact with Controller directly and  Controller can communicate with its associated model. Direct communication between View and Model is not possible. Hence View and Model will have references to Controller only and Controller will have access to associated Model and View. In HMVC pattern, Controller will also have ParentController associated with it, which we will see in detail later. When we create new instance of View its associated Controller and Model should be instantiated, we will call this Model-View-Controller set as Triad. Inter-layer communication  is possible only through ApplicationEvents. AppEvent has its type and name. Event type can be NAVIGATION_EVENT, DATA_REQUEST_EVENT or REFRESH_VIEW. One thing to always keep in mind is each triad/controller knows and handles only those events that it is responsible for. For example, “Login” triad knows only how to log-in user.

NAVIGATION_EVENT: Navigation event is initiated from View, from where it is passed to controller. Controller checks whether it can handle the event or not. If not, then using chain of responsibility pattern is applied and event is passed through hierarchy of its parent controllers. And when the first controller which can handle the event is found, this hierarchy is stopped.

DATA_REQUEST_EVENT: Data Request Event is one which has server communication involved. This is init. from view, and after being delegated by controller its finally handled by Model which does client’ interaction. After response from server, model fires NAVIGATION or REFRESH_VIEW event to controller to show new page/ refresh data that was requested.

  1. View: View has dedicated role for lay-outing the GUI, applying css classes to the components and fireEvents to the controllers when user interaction takes place. As stated earlier, we can divide screen into GUI objects and certain criterias to give it dedicated controller & model can be complexity in the object, amount of navigation inside the panel or amount of data that needs to be transferred with server and frequency of these transfers. Each view will have acces to its child panels. For example, consider diagram below which shows components of “ExamplePage”  in which page is divided into Header, Menubar, NavigationPanel, Preview panel etc. UI object that have dedicated controller and model are outlined in Red. We will name 3 triads in this page as pageTriad, contentTriad, innerNavigationTriad and repectively we can call controllers of  them as pageController, contentController and innerNavigationController.

    "ExamplePage" Components

    “ExamplePage” Components

  2. Controller: Controller’s main responsibility is to delegate events to view/model/parent controller and synchronizing data between view and model. As discussed earlier, controller has associated parentController. For example, consider example above, in which case, parentController of “contentController” is set to “pageController”, parent of “innerNavigationController” is set to “contentController”. Here PageTriad can handle events fired from Menu bar only, ContentTriad can handle events fired from NavigationPanel and it can update preview panel accordingly, InnerNavigationTriad can handle updation in InnerPreviewPanel, however, if there is any event inside “InnerNavigationPanel” to update “PreviewPanel” outside InnerTriad, then chain of responsibility comes into play. InnerNavigationController can not handle this event, so it passes this event to parent controller – “AdminController” which can handle updation in “PreviewPanel”. Here is the diagram to understand hierarchy of triads and how they are associated.
    HMVC Pattern Layers

    HMVC Pattern Layers

    When dataRequestEvent is fired from view, controller has fixed set to steps to do (1) Get data from view and set it to model and (2) Delegate event to model. As we know what we need to do, we can code this in the super-class of controller in following way.

    public abstract class Controller{
     View view;
     Model model;
     public void handleEvent(AppEvent event){
     if(event.getType.equals("DATA_REQUEST_EVENT")){
     setModelData();
     model.handleEvent();
     }
     }
     public abstract void setModelData();
     public abstract void setViewData();
     // getters and setters of view and model
     }

    Here, setModelData() will be abstract method in the super class of Controller. Our all other controller will extend this Controller class. For Example, lets see what if we want to create “Login” widget’s controller. Its setModelData() method would be somewhat like this.

    public void setModelData(){
     model.setUserName(view.getUserNameTF().getText());
     model.setPassword(view.getPasswordTF().getText());
     }

    Similarly, we can write setViewData() method which will synch data of view with model.  After server response is received, model will fire REFRESH_VIEW event to controller and controller can call setViewData() to synch view and then call refreshView() method to actually update view in screen.

  3. Model: Model is responsible to hold data that is displayed in view, communicate with server to get latest data and after server response, fire REFRESH_VIEW or NAVIGATION event on controller.

Here is the class diagram that may help to implement HMVC pattern and identifying what interface each layer needs to provide to communicate with other layer.

HMVC Pattern - Class Diagram

HMVC Pattern – Class Diagram

Summarizing the HMVC pattern, complex UI objects are given dedicated controllers and model that communicate with each other through events. DataRequestEvent go from View->Controller->Model->Server->Model->Controller->refreshView() and Navigation events are handled by controller using chain of responsibility. When the first controller that can handle the event is found, chain ends.

After this initial framework is build, it becomes easy to add new components later or debug existing component. We can also build super classes for each type of UI component for example Page, Grid or Tree.

References:
Javaworld HMVC Tutorial
The Centric HMVC Tutorial

Suggetions and queries are always welcome.

Leave a Reply

12 Comments

  1. Thanks for sharing this.

    The pattern is straightforward to use when a triad (model-view-controller) can handle its events autonomously. What happens, though, when a triad needs data from another triad to complete its handling? What about broadcast events that needs to be passed to all triads (like APP_INIT event)? How do you implement these cases?

  2. Sorry, I don’t have a pratical example but think of it as a View needs additional data to render but these data are not handled but is associated controller (or its parents) but from a “sibling” controller. How an event/response is passed from a controller to controller when they dont have parent/child relationship? Hope I made it a little more clear to you.

    • Hi John,

      I think I was not much clear on explaining that. If you see diagram of “ExamplePage”, or any other screen in any type of web page, at the top most level, we have “Page”, all other panels will be child of Page. In addition to this, every “View” has getter method of its child panel. So when a panel wants to communicate with other panel(sibling), panel will pass event to its parentController. In our case, its passed to “Page”. So “Page” will have getter method of that sibling panel. And it can also call any method in that panel. Thats one of the reason why we have “refreshView” method in every “View”.

      I hope you are clear now..

  3. I have developed user interfaces in two different investment banks using HMVC. I developed the framework as a variation on the original JavaWorld article, and the frameworks were a bit more like the pattern described here.

    My main change was that none of the controllers knew about each other but registered an interest in events which were stored a al Observer pattern in a central object which I called an Allocator.

    This would presumaby operate like the “global parent” and could respond to data requests from any triad.

    This pattern works really well; we found it kept GUI widgets decoupled from each other and from business logic, and therefore made the ui more scaleable.

    • Hi Raul,

      Sorry for late reply. I don’t think there is any standard implementation of this pattern is available. If you wish, I can send you sample code for View, Model, Controller classes.