Developing Component Based Web Applications

Today I started the long but familiar process of taking an existing web application and converting it into a component based architecture. This is the third time I have been involved in an attempt to make the world’s first absolutely perfect web application framework. Unfortunately perfection has not been reached (yet).

This post is just some thoughts that come up when working on a component based architecture. To process these thoughts I am going to compare and contrast how I/we have done it in PHP and Java. It seems to me that component-based (modular) design has a similar learning curve to object oriented design. It sounds like a good idea while you try to learn it and then all of the sudden it just clicks.

Developing a component based architecture requires you to first develop a public API for your components. This API should provide hooks into a component life-cycle that will be run when a component is called. It should also provide methods to tell the component about the environment it is running it (the session, request information, etc).

Here is the CEP (PHP) way:


class CEP_Module {

    public function cepLoad($cep_get_vars);

    public function cepInit($cep_get_vars);

    public function cepPreRender();

    public function cepRender();

    public function cepDisplay();

    public function cepUnLoad();

    // and some accessor methods that are always needed.
}

And here is the Axson (Java) way:


interface IComponent {

    public void init(HttpServletRequest request, Context ctx, String name);

    public String doRender();

    // and some accessor methods that are always needed
}

The Java way may look simpler, and to some degree it is. However, the PHP way is more mature and is to a stage where there are really no corner cases that it cannot handle. The very early versions of CEP may have had an identical component life-cycle (but I think doRender was called runModule). I have a sneaking suspiscion that the Java life-cycle will grow and may look identical to the PHP (CEP) model. The "load" stage is completely cool because it allows any component to act as a component factory, and not seperating preRender and Render has already bitten us in the ass in the Java implementation when trying to display errors from all components in a universal place (which is also very cool).

On the other hand, using the Servlet request and context objects is TONS better than using an array ala $cep_get_vars, but we were already working on that fix for CEP a couple of weeks ago (and it should be done soon).

The next major decision that has to be made when developing a component based architecture is how to go from "components" to "pages". I have handled this different ways in Java and CEP and seen it handled different in Tapestry and ASP.NET (two other component based frameworks that I have come to find sorely lacking for reason that I will probably describe in another post).

In CEP this is handled by defining a "page" as a sort of "primary component". This is nice in that there is no difference in the code that makes up a "page" and a "component" aside from the information in the "site map" (which I will go into in a minute). The CEP way is similar to the Tapestry way in that with Tapestry components and pages are very similar, but Tapestry failed to make them identical (which is one of the reasons I am disappointed with Tapestry). This means that any CEP component can build an entire page. While there is not much repetition there, each "primary component" must call all of the other components required to build a page. We seperated the life-cycle steps that this happens in so that we can still have component re-use but, this feels a little dirty. No component should have that much authority. There is something wrong about the seperation there.

In our budding Java implementation, a pages is based on a "template" (we are using velocity, but that is pretty un-important). This is pretty similar to the ASP.NET way of doing things. I like it because it is simple, but I don’t like it because it feels kinda dirty to me, like a misuse of templates. It is also similar to ASP.NET and Tapestry in that there is a 1-to-1 relationship between pages and files which I think is pretty unimaginitive and we can do better. There is a classic problem when trying to define each page fully in a template file and that is that most pages have the same elements over and over again. While I admit it is much better to repeat ${engine.getComponent("header")} in every template than to repeat that HTML that call represents, it could be better.

Next we always come to the problem of how to map which page request are handled by which classes (modules, components, listeners, etc). We are still working on how to do this in the Java implementation. Currently we are using a little driver system that allows alow of flexibility as long as the result is as hash map. Once again this is simpler than the CEP implementation, but not nearly as robust. In CEP it is tied to the database (though that can be over-ridden using LocalClasses which are similar to ASP.NET’s "code behind"). In CEP we have a robust authentication/permissions tie-in to the "site map" which is something we have yet to explore with the Java.

Ever wonder why I am getting myself involved in two seperate but similar component based framework undertakings? Me too. The main reason is that I am working with two different developers. One who uses PHP because it can do everything he needs to do, and another who uses Java because he thinks it wins on paper. Two good developers that I work well with and plan to continue working with. So for now at least I will work in two different languages until I achieve perfection (which will probably require another language). Until then I am sure there will be more comparitive ramblings here periodically.

UPDATE:
They say a picture is worth a thousand words.

Marcus’ initial diagram of CEP (a new one is in the works):

Cory’s diagram of Axsom:

My generic thoughts on the matter:

    None Found