by Mark Mandel
With the benefits of increased productivity, maintenance, employ-ability, and community testing, you may have finally decided to join the large number of people who are using an open source, ColdFusion community framework for application development. Since the framework space has exploded in the last few years with so many new frameworks and so many different areas, it is very difficult to keep up. So you’re left with a hard task: deciding which framework, or even combination of frameworks, is right for you.
In this article, I’ll explore each framework area available today and give brief overviews of some of the more popular ColdFusion framework implementations in those areas. The goal is to provide some perspective on the vast landscape of ColdFusion community frameworks.
The first type of framework you will likely come across is one that encompasses the Model-View-Controller, or MVCsoftware pattern. A software pattern is essentially a solution to a common problem in software development. In this case, MVC is a solution to the problem of how to keep your View (the HTML) separate from your Model (your data) and being able to coordinate the two in an easy, flexible way (see Figure 1).
Figure 1. The MVC software pattern.
In MVC, the Model includes the code used to access the data that your application uses. Most commonly this is in the form of a database, although it could be external resources such as web services, e-mail servers, LDAP directories, and so forth.
The View is the code that builds what is displayed on the client, which for most web applications will be HTML, but could be Flash, or Flex for rich Internet applications.
The Controller ensures that the correct data from the Model ends up with the correct View so that the application logic performs as expected.
Imagine that you’ve just taken on a new contracting job. You’re working on a legacy system that has seen years of different contractors writing code in several different ways, and it’s a complete mess. There are cfinclude tags that point to modules, which write variables to the client scope, then move them to the request scope before doing a cflocation. Trying to follow it through requires a Mensa membership. Multiple sections of the site are simply "no go," because you know that if you touch any part of them the whole system could come crashing down. It’s impossible to test and impossible to maintain.
So you decide to re-write the site again from scratch. Since you don’t want to get caught in the same trap, you choose to base your application on an MVC framework. Now you have a clear separation between your application flow, and your data and your view. It is far easier to develop, test, and maintain, and if another developer comes along, as long as they know the same framework, their code shouldn’t be that drastically different from your own.
Fusebox, Mach-II, Model-Glue, and ColdBox are some of the more popular community MVC frameworks that are available for ColdFusion.
Among the oldest MVC frameworks available for ColdFusion is Fusebox, which recently had its 5.5 release. Fusebox is based on the metaphor of an actual electrical fuse box in that it contains and controls a series of circuits, each with its own fuse. This corresponds to having a series of circuits to aid in breaking up your Fusebox application into related sections, each with a series of fuseactions that the framework is then able to run when requested by the application.
Fusebox only requires you to write ColdFusion templates; it prescribes neither a procedural nor an object-oriented approach when developing your applications. You can develop your application with just CFM pages, cfinclude tags, or custom tags. Alternatively, you can integrate ColdFusion Components (CFCs). Or you can use a combination of both, depending on your development style. This can be useful for those that have yet to adopt, or are migrating to, an object-oriented approach, and who are looking to ease the learning curve.
One of the advantages of Fusebox is that it gives you the option of using XML to configure your control layer (and thereby your application logic) or using conventions-based CFC to configure it. Using the XML configuration, you can extend Fusebox with lexicons, which enable you to write your own Fusebox actions that can be called directly through the XML. This means you can incorporate your own application logic very easily into the Fusebox paradigm, and reuse it across projects easily as well.
With Fusebox, you can also write plug-ins that allow you to execute code during Fusebox requests, such as when a fuseaction is executed or when an exception occurs.
After CFCs were introduced in ColdFusion MX, Mach-II was one of the first object-oriented frameworks introduced to the community. The premise of Mach-II is that an application fires a series of events, and each event implicitly invokes different aspects of the controller code base.
This means that aspects of your application can be invoked, either through an event fired from a URL, such as http://www.foo.com/index.cfm?event=doThing, or through an event fired by the application code itself. Mach-II uses an XML configuration file to route those events to a series of listeners and filters and thereby determines what functions to invoke on them. This is why it is referred to as an implicit invocation framework.
The listeners and filters within Mach-II provide the main points in the framework in which to write your Controller logic code and enable your Model to provide the functionality for your application. Mach-II also gives you plug-in mechanisms, which allow you to intercept aspects of the framework globally, such as before and after a Mach-II event occurs.
The XML configuration file for Mach-II makes it easy to understand the logical flow of your application. It is laid out in a very sequential manner, which can be surprisingly helpful for those who are not used to framework development.
Recent developments in Mach-II, as it heads towards a 1.6 release, have included built-in caching and logging functionality as well as other extensions to provide developers with more pre-built tools to build their applications.
Model-Glue is another object-oriented framework for ColdFusion that operates on an event-based, implicit invocation paradigm with an XML configuration file. It works with a Publish-Subscribe software pattern, however, which is slightly different from how the previous frameworks were developed.
Much like the idea behind a magazine subscription, message listeners can be registered to receive event messages that are then broadcast to them. This allows you to set up multiple listeners to receive the messages that are broadcast, giving you a flexible way to develop and extend your application through a highly decoupled system architecture.
Since version 2, Model-Glue has also had direct integration with ColdSpring, a dependency injection framework, and Transfer and Reactor, two popular object-relational mappers for ColdFusion (discussed later in this article). This means that Model-Glue can provide functionality such as scaffolding, to generate and display a basic user interface for listing and editing database data, which can be very useful for application prototyping and development.
Model-Glue 3, currently in alpha, also provides some really interesting new features, including development-time code generation, and tighter integration with ColdSpring for CFC dependency injection into listeners.
ColdBox is one of the more recent MVC frameworks offered to the ColdFusion community. It has picked up a lot of momentum and development over the last twelve months. Like Mach-II and Model-Glue, it is also an object-oriented, event-based, implicit invocation framework. What sets ColdBox apart from the crowd is its relative lack of XML configuration.
ColdBox uses conventions to match handler CFCs within a specified directory, and methods within those handlers to ColdBox events that can be fired either from the URL or from within the application logic. As such, there is only a single XML file for configuration settings; however the logic of your application is purely managed by CFML.
ColdBox also lets you intercept framework specific events, such as application start-up, session end, or event processing, using interceptors, which you can also extend to allow for your own application-specific interception points.
A wide variety of application building tools, called plug-ins, also come bundled with ColdBox. These include caching support, error handling, logging, and integration with dependency injection frameworks ColdSpring and LightWire, which can greatly increase your productivity as they make many of the common tools you need to develop applications available to you.
Imagine you have been writing your application using a MVC framework, and it's going along very well. You have also started placing some ColdFusion Components (CFCs) in your Application scope so you can access them readily without recreating them on every request. So far you have five CFCs in your Application scope, and that has been manageable, but as you develop it looks like you will have ten, and then thirty! Several of these CFCs require each other to work, and you start to realize that as you attempt to juggle creating all these CFCs and their dependencies when your application starts up your Application.cfc is looking much like the spaghetti code you were trying to avoid in the first place.
Before things get too crazy, you can implement a dependency injection framework. Now when you need a CFC, you simply ask for it from the framework, and it hands it to you. You no longer have to worry about what relationships it has to other CFCs, and what order they get created, and it doesn’t matter if you have ten, twenty, or one hundred CFCs, you know they will always be managed for you.
ColdSpring and LightWire are dependency injection frameworks that are commonly in use in the ColdFusion community.
ColdSpring was the first dependency injection framework for ColdFusion. Taking much of its inspiration from the Java Spring project, it uses an XML file to enable you to configure your CFCs and their dependencies. These dependencies can be explicitly set, or if ColdSpring is set to autowire it will introspect the meta-data of each CFC it instantiates and resolve the dependencies automatically.
Once your XML file has been configured correctly, you simply request CFCs by the name specified in configuration, and ColdSpring manages the instantiation of the object as well as any dependencies along the way.
While ColdSpring manages dependency injection, it also provides functionality for aspect-oriented programming, which enables you to wrap code blocks before, after, or around different parts of already implemented CFC functions at run time. With ColdSpring aspect-oriented programming you can also use RemoteProxyFactories for exposing services to remote invocations.
LightWire is another dependency injection framework. Unlike ColdSpring, it also provides a programmatic interface in addition to allowing configuration through XML. This can be useful if you are not very familiar with XML, and simply want to use regular ColdFusion to outline your object dependencies.
While LightWire does not provide any additional functionality above and beyond dependency injection, it is a very lightweight framework. With only two CFCs, LightWire can be integrated and deployed easily with almost any project and with a minimum of overhead.
Persistence frameworks were designed to reduce the amount of work needed to develop an object-oriented system that stores data in a relational database. The structure of in-memory objects does not match up well with the structure of data in relational databases, and it can be a slow and repetitive process to develop all the code that is required to move the information between the object space and the relational space. For this reason, this framework area is often also referred to as object-relational mapping or ORM (see Figure 2).
Figure 2. Object-relational mapping.
The goal of a persistence framework is to automatically map objects to and from a database seamlessly so that information can be quickly and easily retrieved in object format, and then subsequently stored in its relational structure. This aids in system development and maintenance greatly. The mundane details of writing your own create, read, update, and delete functions are taken care of for you, so you can concentrate on designing and building your application.
Consider a project in which the application configuration is working smoothly. Your Model, View, and Controller logic is separated wonderfully, and your dependency injection framework is handling your CFC relationships. The annoying thing is, you’re spending three quarters of your time writing boring SQL statements to put data in the database, take it out, and edit it. Writing that SQL and matching it with CFCs that represent the data makes developing your application really slow, and maintaining it requires you to make numerous changes just for something simple, such as adding a column to a table.
If you use a persistence framework, things are far easier. You don’t have to write the SQL to do create, read, update, and delete operations anymore — it is generated for you. Pulling information from the database is as simple as requesting a CFC that represents it from the framework. To update that data, you simply pass that CFC back to the framework, which manages it for you. Suddenly you find that you are spending far more time working on how your application is meant to function and how to design it, rather than the mundane details of pushing and pulling data from your database.
Transfer and Reactor are two persistence frameworks that are currently available for use with ColdFusion.
Recently released, Transfer version 1.0 is an ORM for ColdFusion based around the concept of business objects, which represent a singular entity, such as an employee, a product, or an order within an application.
From an XML configuration file, Transfer is able to generate these business objects at run time, providing much of the basic functionality you would need to develop your application, such as get, set, and object composition functions. These business objects, called TransferObjects in the framework, can be retrieved from Transfer with their required information, and then modified as necessary. TransferObjects can be passed back to Transfer, for automatic persistence into the database.
You can extend generated TransferObjects via the Decorator software pattern, in which you write a custom CFC that is wrapped around the generated TransferObject and has access to all its built-in functionality. This is particularly useful when you need to write your own custom business logic in the objects that make up your application.
Transfer also provides a configurable caching layer, a scripting language for database-agnostic querying, a Publish-Subscribe model for observing Transfer events, and many more features.
Reactor is a ColdFusion ORM that is based on the Active Record design pattern, rather than a Transfer Object pattern. This means that each object that represents data is responsible for its own persistence. In other words, a Reactor Active Record object saves its own data and retrieves its data from the database, rather than asking an external service.
Reactor also generates CFCs for you, however it does so by providing a development mode that enables it to generate not only the Active Record objects, but also generic Data Access Objects and Gateways. The code generation is powered by a combination of XML configuration and database introspection, which can be quite useful, as it does provide you with a large amount of usable code with minimal effort.
The extension mechanism for Reactor is through inheritance, in which your custom code will extend the Reactor-generated CFCs to provide the custom functionality and business logic that you need for your application.
To summarize the main development frameworks for ColdFusion:
These three types of frameworks can cut down your development time considerably by providing you with a set of proven tools to solve common development problems.
The framework landscape right now in ColdFusion provides a variety of robust, mature, and sophisticated frameworks, including several that have not been discussed in this article. Which one you choose boils down to your immediate needs and personal preference.
There is no mythical silver bullet, and thus there is no right choice. You can use the information in this article along with further details from the referenced framework websites to make an informed initial choice of one or more frameworks. As you test frameworks for your application, keep in mind that at the end of the day a framework should enable you to be more productive.
Mark Mandel is the author of several open source projects, most notably Transfer ORM and JavaLoader and has been working with ColdFusion for a number of years. You can often find Mark blogging and consulting at www.compoundtheory.com.