We had a post on the wicket-user list earlier this week, where the author of the post asked how to use a more fixed navigation model for Wicket.
First, let me state that any navigation model is entirely doable (and even enforcible if you want to go through the effort) with just a couple of simple classes. Wicket does not enforce any navigation model on you, and leaves the door open for you to decide on this. That seems to confuse people every now and then, especially those programmers that have been using other web frameworks in the past.
This remark in that email is what triggered me to write back a lengthy response:
‘One of the most ideal solutions I’ve seen to date is the implementation
of JSF, where navigation logic is defined in a separate descriptor. I
know this is counter to the philosophy of Wicket, but in separating the
navigation logic from the page definition, JSF achieves the goal of
modular application architecture with elegance.‘
Here is my slightly modified reply, saying I disagree because:
‘First of all, there is the matter of abstraction. If you want a JSF-like navigation model, please go ahead and implement that. A couple of classes are enough for that. Whereas JSF forces you into one navigation model, Wicket doesn’t.
Secondly, what exactly is page navigation anyway? There are many ways to
group your functionality. Using pages, Wicket’s top-level component, is one of them. If you define different pages for all the combinations of components you’ll use in your application, a page oriented flow mechanism might actually work. However, that way of looking at grouping functionality is a bit outdated. It is the traditional, document oriented approach, which is fine for … document oriented sites. Wicket is a good choice for more complex user interfaces that resemble desktop applications. If you take a step back and think about how you would code the application you’re working on e.g. using Swing, it is quite unlikely that you would use a bunch of windows/ frames with a factored out navigation mechanism. More likely, you would start with a window/ frame, and from an initial stack of components, you would enable/ disable/ hide some components, replace (or stack) panels, etc. This is in fact my favorite approach for Wicket, with the exception of where locations should be bookmarkable.
Lastely, there is the issue of reusability. The application I currently am working on has many components that are fully self contained, including it’s ‘navigation’. I think it is great to build components like that and use pages mainly as an entry point and to group larger/ high level blocks of functionality. A public example of this is the wizard component, which can be found in the wicket-extensions project. That component will function on any page/ with any combination of components. And with no additional flow configuration you have to adhere to.
A funny side effect of AJAX getting popular is that it proofs that forcing yourself into a page oriented flow model doesn’t make sense. Look at GMail, Flickr, and all of those web 2.0 ajax driven apps… they surely don’t use such a flow mechanism. Sometimes they replace 3/4 of a screen, sometimes just one widget, and sometimes they do replace a whole screen (though Gmail, really rarely does that). The good thing about Wicket is that you can structure your applications in exactly the same fashion as those applications, and you can decide later on to ajax-ify or de-ajax-ify parts of it, without major restructuring. So instead of suddenly having another ‘navigation approach’ when you use ajax, with Wicket it all fits in the same approach.’
Basically my point is – in case that wasn’t clear yet from the above reply – that declarative page navigation is a bad idea that is in 3/4 of web frameworks because people are either blindly following old ideas, or they like to build stuff without thinking first why they would need it and whether they choose the best abstraction.
One of the worst things of model 2, but also any ‘flow driven’ approach, is that it is very procedural. Rather than trying to define what objects you have, and how they should interact (OO), you’ll be focussed on how to do stuff (if this, then that, if that then foo) And if procedural programming is your thing, why would you pick Java?
By pulling the navigation out of components, you’ll loose the ability to make that navigation an implementation detail of that component (like the wizard does). And as the navigation will be handled by some intermediate piece of software, you’ll open up a whole can of worms like how to pass information between steps, how to conditially make transations, etc. Before you know it, you’ll need a seperate framework for this, with it’s own DSL, tooling and fame-aspiring authors ;)
A final remark about ‘flow’ is that lots of people probably confuse workflow/ business process management (BPM) approaches with the kind of flow that is regularly promoted in user interface frameworks. They should be regarded different things. If you choose a BPM driven approach for your project, your user interface, or at least parts of it, should be driven by the BPM engine. I haven’t looked into Seam in regards to how it integrates with jBPM (which btw is one of my favorite open source frameworks), but I’m suspicious that they promote BPM for the wrong reasons. If workflow is not a major business concern in your project, you’re probably using a domain driven approach. It that is the case, think twice whether you really need formalized flow.