Architecting with Fusebox 4.1 is a very wide arena. There are lots of ways to do it, but I think I found one that is particularly well suited to the framework, especially when combined with CFCs for a backend. My presentation at the 2004 Fusebox Conference hinted at much of the principles, but I can say that after having written a couple more FB4.1 apps from scratch, that they make for a very nice little package.
There's a few main points:
- Separate 'pages' from 'actions'
- Separate the UI from the application proper
- Separate the markup from the presentation
- Reuse code everywhere it makes sense, and nowhere else
For point #1, a legit question might be "what's the different between a page and an action?". My definition is that a page renders content to the user, while an action performs an action and redirects to somewhere else. The definitions are mutually exclusive, so if you're doing an action, you HAVE to redirect to a page in order to render content; you can't do both on a single request. There are a few exceptions (for instance, marking a message 'read' – an action, when you open it – a page), but they are few and far between.
I opted to have all my fuseactions that generate HTML be named as you'd expect (addEntry, viewComments, etc.). All my fuseactions that do actions start with 'do' (doInsertEntry, doDeleteComment, etc.). In my presentation at FBCon04, I'd recommended separating the pages and actions into separate circuits. Upon further reflection, I'm retracting that recommendation in favor or just separating the pages and actions in your circuit.xml file. One block has all the pages, and another block has all the actions (commented appropriately, of course).
Point #2 is accomplished by the use of a 'service' CFC. It is a singleton CFC that is instantiated into the APPLICATION scope of the app, and it contains all the business operations and data recall for you app. Each business operation has a defined method name and set of parameters. How it's implemented (inlined SQL, a mess of BOs, DAOs, and gateways, magical pixie-powered light-based storage, whatever) is irrelevant, and that's exactly the idea. You should be able to change your presentation layer without changing your service object, and you should be able to reimplement your service object (maintaining the method signatures, of course) without changing your presentation layer.
Point #3 is the standard "use (X)HTML and CSS" line. Make sure you pages are designed from a semantic perspective. Build all the pages before you ever write a single line of CSS. Not going to be pretty, but they do need to be functional in that fashion. Then whip out your CSS magic wand and make it all pretty. This really has nothing to do with FB4.1, but it does have to do with good architecture, because the more divorced your markup is from your presentation (CSS, in this case), the easier it will be to make changes (visual or functional) down the road.
And at last, number 4. Two clauses, and the latter is the more important one. I've seen a lot of people (myself being one) who try to squeeze every last drop of reuse out of a bit of code. Reuse is good, but there are definite times when it's simply a foolish goal to strive for.
In this particular app, most of my display templates (roughly analogous to views in Mach-II) are in their own fuseactions. Again, I opted to not use a separate circuit, but rather name them starting with an underscope (i.e. _entryForm) set them as access="internal", and group them all in their own section in circuit.xml. They include everything needed to render the view, except for designated parameters for reuse (such as the XFA to submit a form to). That means they might include calls to the service object for a recordset, might set their own XFAs, might do basically anything, as long as it's bound directly to rendering that specific view file.
So, in a nutshell, what do I have? A single circuit, broken down into three sections (pages, views or pagelets, and actions). An abstracted service object that encapsulates all the business and persistent operations behind a known interface. Markup that is independant of it's presentation. An app that is both enormously flexible and easy to work with.
Future updates can apply to single sections of the app without affecting other sections if they don't need to, greatly reducing the subsequent testing needed. Poorly implemented sections (of which there are a couple because of time constraints), can be transparently reimplemented without affecting the app.
What I've described isn't quite MVC, at least in the traditional sense. It's subtly different, and while only time will tell, I think those differences result in a much better end result.