Even though I’ve been at a project that uses Spring Webflow for over a year now, I havn’t gotten to use it much. Part of it is because I’m running around in meetings, other part is because I have been focused on architecture and back end programming. But those are the “easy” parts. I don’t really mean easy, but it’s on the GUI side of an application you find all the funky code where everyone is doing their separate thing and messing around with requests and sessions. My previous experiences mostly include Struts, so I’ve seen and performed my share of framework misuse. 😉
Spring Webflow tries to encapsulate this and abstract everything away, but it can be misused in a number of different ways too. Where there is a will there is a way. 😉
The following is my initial experiences with a relatively simple flow. Some of the tips have not really been tested yet, but hey, you learn by doing the wrong thing too don’t you? 😉 We tried hard to maximize usage of webflow code and support, and minimise our own. Readability and maintainability was also a major concern.
Stay object oriented
If you can, reuse your domain objects. If you have to create a specific object to keep extra data, reuse as much of the domain objects as possible. This can be achieved by inheritance or composition, I tend to lean towards composition. This also means that an ISBN number should be an ISBN-object, not one of those god awful Strings. 😉 Check primitive obsession for the details: http://www.jamesshore.com/Blog/PrimitiveObsession.html.
Use binding mechanisms
This is closely related to the previous item. Spring and Spring Webflow uses the notion of binding to figure out how to convert request parameters (that’s really all the text you type in a form is) that are Strings, to what is expected in the object you use to represent the form (and this is ideally your domain object, remember?).
If you have a ISBN object in your form object, Spring will detect this and use the custom binder you supplied for this. This is of course a highly reusable class based on the java.beans.PropertyEditor interface. This can be reused in every form you have a ISBN number, and it will parse and validate that the entered String actually is a ISBN number. You can of course choose to ignore it if it does not parse, and do the extra validation in your validation step, but I really don’t see any reason for this. If it doesn’t bind as a ISBN there is no reason to validate later on either. The end result? You reuse code, and can focus on working with well behaved objects in all other parts of the system.
Use a FormAction object to implement logic
Webflows are usually defined in XML. It is possible to define them in Java, but I havn’t tried it yet. When specifying it in XML they can get pretty large and unmaintainable, with lot’s of XML for calling services and setting results on scopes etc. One of the best ways we have found to resolve this is to use a FormAction object.
FormAction is one of Spring Webflows own objects that we extend and create methods on. It has access to classes specific to Webflow and thus access to special scopes etc. If you then want to show all the books available in you database you would call the retrieveAllBooks method on the FormAction. This method would then retrieve from the database (service/repository) and put it on the flash scope for the JSP (yeah, we probably should experiment with different view technology too) to display.
This relieves us of all the clutter of defining input parameters to methods and returns in XML which quite frankly looks quite nasty. It does however communicate intent in the XML so you can roughly understand from the flow what it is meant to be doing. Creating one mother method here would of course remove that advantage, so keep them short and have descriptive names.
Unit test your flows
This is actually one of the biggest surprises for me; that I actually liked it. I thought the cost/value ratio for unit testing webflows was too high, but once I got a hang of it, it had incredible value. This might be partially due to the fact that changes to a webflow don’t propagate before you reload your webapp. Never the less, being able to test how it responds to changes in what was on the request proved invaluable. But do watch out; not everything should be tested in your webflow test. Remember you are testing the flow.
It’s a bit of a learning curve, but do use it.
In the end…
Overall impression is that it’s a really good framework for flows. I was partially convinced earlier on, but the last days of experiences really won me over. As I said initially my trials was done on a relatively simple flow, but I believe I discovered enough to extrapolate this to many other cases too.
Please do add other experiences in the comments. 🙂