Scoreboard
Ease of Development
How much effort was needed to develop the application?
- JavaServer Faces
- The backing bean and JSP pages were reasonably intuitive, if a little verbose.
The configuration files, however, are a source of significant pain. There is a considerable amount of XML in proportion to the size of the application.
- Tapestry
- A clear and straightforward relationship between the code and intent, with highly informative error messages, makes development a breeze.
- Stripes
- Ensuring that the source files are in accordance with Stripes conventions was somewhat tedious and error prone.
However, an experienced Stripes developer could presumably arrange this without too much difficulty. Once applied, the conventions did ensure fairly simple code.
- RIFE
- The XML approach requires a great deal of XML, which must be synchronised with the templates and Java code. Not a very attractive proposition,
which is why the continuations approach was taken instead.
- A considerable quantity of code is required to handle the wiring between the template and model classes, including a metadata class.
The code to handle flow control is also rather verbose; altogether, it appears that excess XML has merely been replaced with excess Java.
Worse, RIFE continuations have been hacked into a language which cannot properly support them.
Although the implementation is ingenious, problems abound. The fullName property had to be moved out of the model class (Name.java), due to excessive difficulty
in surviving cloning and continuing, and handled explicitly in the controller class (Rife.java).
Handling nontrivial (although far from complex) flow control seems to be something of a black art.
However, a wealth of examples are offered, which helps considerably.
- Wicket
- The everything-is-a-component approach requires some getting used to. The advantage is that, one you understand Wicket components and their models,
you understand most of what their is to know about wicket. The disadvantage is that trying to model everything as a tree of Wicket components
and models can lead to rather a lot of convoluted code, much of it unrelated to the problem domain.
Another downside of Wicket is that all the components have to be created in Java. As can be seen in Index.java, this requires a great deal of code.
Every other component-orientated framework creates the components from markup, a much less laborious approach.
- The Wicket application actually cheats for flow control.
WizardStep.Evaluate() is used to skip screen B; a more complex scenario would require a considerable amount of work to customise the WizardModel.
- ASP.NET
- This was fairly easy to develop. Only two files were needed, both of which were created by the IDE.
Visual Studio's visual designers and excellent text editor made light work of a simple task.
- ASP.NET MVC
- Although requiring many more files and directories than regular ASP.NET, the Visual Studio project template creates an initial directory structure,
and automates the process of adding new files.
- PHP
- Coding the PHP was a moderate effort. Although there is no complex configuration or boilerplate, there is very limited assistance from the framework; all the mapping and session storage must be hand-coded.
- Ruby on Rails
- Although all the Ruby source was written by hand, this was highly intuitive. One issue with the model is discussed in the next section.
- Seaside
- Smalltalk's environment is a joy to work in, although dynamic typing adversely effects the IDE's understanding of code.
(For example, you cannot browse to an identifier's class, as this is not statically defined.)
- The back and next buttons could have been hard coded into every screen, but Seaside components are so easy to create
that it was almost trivial to write a quick-and-dirty wizard component.
- WASH
- This was a very straightforward program to develop - the single code file approaches the clarity of shell scripting.
- Arc
- Arc is in a very early development stage, hence many bugs and a rather rudimentary library. Presumably this will improve with time (and Anarki).
- The application code itself is very straightforward, similar to WASH, but without the monad plumbing.
Bookmarking
What will happen if the user bookmarks the middle of the application, and returns to it next week?
- JavaServer Faces
- The server is liable to throw a null reference exception, as the backing bean has not been properly initialised.
- Tapestry, ASP.NET MVC, Ruby on Rails
- The application will commence from the bookmarked location, with default data.
- Stripes
- Every page appears with the URL app/App.action, so bookmarking and returning later will simply start the application afresh.
Stripes is very forgiving of empty fields, so even if a user went directly to e.g. app/B.jsp, the application will function with default data.
- RIFE, ASP.NET, WASH
- There is only one URL/template, so bookmarking and returning later will simply start the application afresh.
- Wicket
- An internal error, as the action URL does not match the form data.
- PHP
- The application will resume from the middle, with missing data. This is liable to cause an error, when attempting to retrieve a missing POST or SESSION value.
- Seaside
- The URL contains the application entry point, and a session/continuation identifier. Attempting to return to an old URL will
revert to the corresponding state if the continuation is still valid, otherwise the application will begin afresh.
- Arc
- "Unknown or expired link"
Browser Navigation
What is the effect of using the browser's back and forward buttons, then interacting with the displayed page?
- JavaServer Faces
- The application will behave as expected, using session data in the server's memory.
Entering data, pressing the browser's back button, then the application's next button, will cause the old data to reappear.
However, the server can be configured to serialise the session bean to the page as a hidden form field,
in which case old data will not reappear.
- Tapestry, RIFE, ASP.NET MVC, Ruby on Rails, Arc
- The application will behave as expected, using session data in the server's memory.
Entering data, pressing the browser's back button, then the application's next button, will cause the old data to reappear.
(Although Arc uses closures, only the last closure for a session is kept.)
- Stripes, ASP.NET, WASH
- As all the state information is streamed to the page in a hidden field, these buttons will work as expected.
- Wicket
- Information about the application state is stored in hidden fields.
Disaster will ensue if this does not remain synchronised with the URL and server data.
- PHP
- As long as the browser retrieves the page from its cache, the application will simply continue, overwriting existing session data.
However, if the browser attempts to retrieve a new copy of the page out of sequence, this may cause an error, due to the expected POST data not being present.
- Seaside
- The application will behave as expected.
Entering data, pressing the browser's back button, then the application's next button, will not cause old data to reappear.
Forking
What if the users forks the session into a second browser window?
- JavaServer Faces
- The backing bean will be shared between the two instances, because they have the same session identifier. Each session will overwrite the other's data.
If the server is configured to serialise the session bean to the page, the sessions will be kept separate.
- Tapestry, ASP.NET MVC, PHP, Ruby on Rails, Arc
- The state will be shared; each session will overwrite the other's data.
- Stripes, ASP.NET, WASH
- As the state is held on the page, two independent sessions can proceed simultaneously.
- RIFE
- The continuations appear to be shared between the sessions; each will overwrite the other's data.
- Wicket
- The hidden fields, URL and server data will become desynchronised, causing a fatal error.
- Seaside
- The two session will work independently, using different continuations.