Framework Comparison

This is the raw feature comparison matrix that I created as the basis for my frameworks comparison talk that focuses on Mach II and Fusebox. I've recently added columns for Model-Glue which means that you need a wide screen to view the table easily. Sorry about that. I'm open to suggestions on how to make this easier to read but I'm not going to bust myself on it - it's just raw data for your information, OK? If you want, you can download the raw .xls file (created in NeoOffice/J).

Some notes about the table:

Feature Same Different FB Pros FB Cons M2 Pros M2 Cons MG Pros MG Cons GGCC Example?
XML All use XML config files FB has multiple XML, M2/MG has one XML Easier to manage, can reuse Hard to see whole app at once Easier to see whole app Hard to manage when it gets large (M2) (M2) fusebox.xml.cfm and circuit.xml.cfm, mach-ii.xml, ModelGlue.xml
MVC Can use MVC FB allows but does not enforce, M2/MG pretty much forces it Easier to learn Easier to write spaghetti code Easier to stick to best practice Harder to learn (M2) (M2), but not as hard as M2 GGCC3-7 are MVC
MVC Structure Model/View directories FB typically has controller circuit directory, M2/MG has implicit controller in framework Structure is more explicit Multi-circuit approach can cause duplication Simpler organization: model is CFCs, view is CFML None (M2) (M2) Show each apps directories
CFCs Can use CFCs FB allows but does not enforce, M2/MG pretty much forces it Easier migration path from old school code None Easier to stick to best practice Harder to learn (M2) (M2) GGCC3-7 use CFCs
Plugins All have plugin points FB has more plugin points, M2 distinguishes events and views, MG has simple request/queue model Finer grained control over processing More complex Supports pre/post-view plugins Not very granular Easy to learn since 'plugins' are just controllers No real plugin concept so it isn't as powerful GGCC4/5 have M2 plugin, no FB plugins
Access control All have private / public concepts FB has per circuit and per fuseaction as well as roles-based model, M2/MG has per event access only Finer grained control over processing None None Not very granular (M2) (M2) All but GGCC1 use public/private somewhere
Auth / Security None FB has roles support builtin, M2 provides a sample filter, MG is free form Some builtin infrastructure If roles-based security doesn't meet your needs, you have to start from scratch None You have to build it all yourself (M2) (M2) None
Install / Config One-stop core files, basic properties in XML file One-stop core files is brand new in FB41, FB provides finer control over framework behavior, MG has a simple framework control model More control over framework behavior More parameters to learn Simple infrastructure in place for quite a while Not as much control over framework behavior, requires both <cfinclude> and CFC-creation setup (mapping and custom tag paths) (M2) (M2) The examples assume you have /fusebox4, /MachII, /ModelGlue either as mappings or in your web root
Modularity of Application None FB has circuits to partition large applications Better modularity None None No support for partitioning applications (M2) (M2) FB examples use multiple circuits
Modularity of Site None M2 allows multiple sub-applications to share application scope None No single sign-on across multiple apps Single sign-on across multiple apps Sub-applications cannot share properties etc (FB) (FB) N/A
Commonality Can explicitly invoke fuseactions / announce events / add results to handle common functionality FB has per-circuit pre-/post-fuseaction hooks, providing framework level support for commonality Some builtin support for commonality More complex, more options None All commonality must be explicitly programmed (M2) (M2) GGCC1 uses <prefuseaction> and also reuses common fuseactions (see taskmanager circuit)
Views All encourage views to contain “only HTML” (no logic) FB/MG lets you include a view directly, M2 requires that you declare all views in XML Simpler, less XML to write If you move a view, you have to change every reference to it You can move views around and only change a single declaration in the XML file A lot more XML to write (and it's very tedious) (FB) (FB), although you specify the view location via a mapping which means you can move all your views to a new location and only change one XML setting GGCC4/5 cheat a little since they use <view-page> directly rather than separate view events (which would better match the FB examples)
Handler Model All declare 'handlers' for 'events' in XML FB is a static, explicit invocation model, M2 is a dynamic, implicit invocation model, MG is somewhere in between Simpler, more intuitive for web developers; Performance is good because static execution model can be compiled to inline code You cannot 'do' a dynamic fuseaction, e.g., from a database, so certain dynamic applications are hard to write entirely within the framework Implicit invocation provides looser coupling, more flexibility and more dynamic power within the framework The event queue model is very hard for many web developers to grasp; Dynamic interpretation of the event queue has a performance overhead (M2); Messages are processed as they are broadcast (rather than being queued); Broadcast / listener model is even more loosely coupled than M2 The event model is essentially static (like FB) but interpreted (like M2) although the performance overhead is lower than M2 No real example of this
Data bus Can use request scope as data bus (but it's not always best practice) – MG uses event object FB allows variables scope as data bus; M2 allows event object as data bus, MG enforces event object as data bus Simpler – one scope (variables) can be used throughout No encapsulation Event object is a nice encapsulation Framework doesn't fully support event object as a data bus Very consistent – all data is passed via the event object which becomes the view state None GGCC4 needs to do a lot more work to maintain the event data bus but FB apps are inconsistent about attributes, variables and request scope
Global data None FB has fusebox.init.cfm, M2 uses either <property> tags or plugin (or both), MG has settings Simpler – one file contains all global data setup Application data initialization needs to be explicitly coded Automatic management of application data <property> is restricted to simple string data so plugins are often required (M2) (M2), although you use controllers instead of plugins and the event object instead of updating the settings All the FB examples (GGCC1/2/3/6) use fusebox.init.cfm for globals, M2 (GGCC4/5) uses a combination of <property> tags and plugins, MG (GGCC7) uses a combination of <setting> tags and controllers
Model CFC Structure Most CFC methods could be the same FB uses standard init() construction controlled by explicit code in fusebox.init.cfm or circuit, M2 reserves init() and uses a managed configure() method to initialize CFCs – with no arguments – and CFCs must extend the framework, MG has base controller init() method Simpler – CFCs can be independent of framework and follow standard best practice Construction needs to be explicitly managed Standardized infrastructure to manage CFC lifecycle Complex, requires integration with the framework and non-standard CFC structure (M2) CFCs must extend and initialize the base controller Compare GGCC3, GGCC4 and GGCC7 to see how the different frameworks handle this
Conditional logic None FB has some conditional logic in the XML grammar, M2 requires conditional logic placed in CFCs, MG requires controller CFCs Simpler XML controller can get polluted by logic Clear delineation of declarative configuration and procedural logic Requires more code is written (M2) (M2) User identity is a good example in every variant
Model Actions All have the concept of separating business model logic from presentation logic FB allows a model action to set multiple outputs, M2 uses strict call/return semantics so each action can have only one result, MG allows a model to set multiple outputs via event object An action can 'do' more in terms of setting up a data environment for subsequent actions, queries or displays Risk of spaghetti code since an action can set arbitrary outputs Simple interactions with the business model Often requires either more roundtrips to the business model or use of complex data structures to simulate multiple results (FB) (FB) Compare GGCC2 with GGCC3 to see how the single return value affects things; GGCC7 goes back to multiple results
Model Queries None FB specifically separates out persistence operations (by a naming convention on files), M2/MG draws no distinction between actions and queries Better organization of code None Consistent framework interface (listeners) Need to use design patterns to manage separation of persistence (M2) (M2) Both GGCC3 and GGCC4 blend persistence into main model, as does GGCC7