Monday, January 31, 2011

Yes, but WHAT IS A CONTROLLER??

I asked Simon Lessard (a guru among gurus for Java and ADF) in the ADF Methodology Group about what he thought a controller was, and his response is of great interest to me; so I am going to publish it.

From it I learned that Struts did not use the event model, what an Observer pattern was, and a better way to organize your backing bean (controller bean/data bean) code.

From this thread, we have the following:
Hi Michael,

It depends, "controller" can have many meanings. In the purist version, the MVC model is a triangle (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). The model exposes the data and services, the controller is the one in charge of calling the model, and the view represents it, calling the controller whenever a UI event occurs and observing (observer pattern http://en.wikipedia.org/wiki/Observer_pattern) the model layer for change and updating itself if something happens.

Now, since the Web model is a detached one, that last interaction is not possible so the MVC model in the Java web world is a mutation of the pure one. As of Struts, the controller was defined as the component in charge of managing the page flow, the navigation of which was implemented by two type of entities, the Action and the struts-config.xml file (and the control flow engine running it). With JSF, the event model like that of Swing was added, providing a way to implement another part of the controller layer -- the UI event management -- through various listeners. Each listener can therefore be considered a controller or part of a bigger controller (depending how you implement it) since these listeners can modify the component (refresh it, change its state, etc.). Also, since those listeners are accessed through EL and call managed bean methods in the end, then yes, I consider some managed beans a controller (or a part of a controller) -- but only if they are not used to store data. I call the latter data beans, and they often implement an interface from the model layer so that they can be used as service call parameters. So, in the pages, you have:

<af:inputText value="#{expressionToADataBeanField}"/>
<af:commandButton action="#{expressionToAControllerBeanMethod}"/>
<af:someComponent binding="#{expressionToAControllerBeanField}"/>

Since the controller bean often needs access to the data bean, I inject the data bean into the controller bean (using the managed-property feature of JSF) when the controller is created. The data bean is stored in a persistent scope like session or page flow and must therefore be Serializable. The controller bean, on the other hand, must be stateless; so it can only be placed in the backing bean or the request scope and cannot be Serializable since UIComponent (the root class for components) isn't and can be bound in the bean.

So yes, I call a backing bean a "controller" since they manage the UI interactions, call the model layer services and participate in the navigation through the action's outcome which is everything a controller should do. However, the controller layer is also completed by the JSF's NavigationHandler, which takes care of the actual page flow from the outcomes.

So to summarize, I consider:
- Managed beans used to bind components and deal with events: backing beans, controllers, controller beans
- Managed beans used to store the data entered by the user: data beans, page flow beans, session bean


I hope it clarifies the concepts a bit,

~ Simon

No comments: