How Model Glue Failed Me
This is a post that has been gestating in my brain for years. It is all about frameworks, the model view controller design pattern, building ColdFusion applications and why I hate the Model Glue approach. I don't consider myself anti-ColdFusion or anti-framework, but I do consider myself anti-Model Glue. I finally decided to sit down and get it down on paper.
On some of the more private places in the ColdFusion community, I have been quite belligerent in regards to Model Glue. I had used it for clients in the past, however a few times and when hiring someone to build the Flextras site, I stated if that if the vendor was going to use a framework, then it should be Model Glue.
It was the ColdFusion framework I had the most familiarity with, so I felt that made sense. I left the final decision up to the vendor, and they built out the site in Model Glue.
This was a very bad decision.
The end result is a site that is hard to maintain. It is hard to follow the logic of how pages are put together, as redirects often mask what is going on under the hood, and it difficult to tell when a redirect occurs.
As one example of my frustration, when I added an instance of BlogCFC to the site, it took days to use the standard header and footer code from the site on the BlogCFC pages. This task should take hours at worst, or minutes at best. The code was not set up for reuse. There are performance issues with the site, and it is not uncommon for customers to see timeout errors if the site has been inactive for too long and the framework needs to reinitialize.
The whole thing has left a bad taste in my mouth for how Model Glue was implemented. A lot about the way that Model Glue is implemented appears to go against my basic programming background and it appears to fly in the face of my innate desire to write encapsulated, reusable code.
What is Model View Controller?
Model Glue is one of many ColdFusion frameworks intended to help us programmers implement a Model View Controller architecture in ColdFusion. Model View Controller (MVC) is a popular design pattern, and is often considered the epitome of perfect development. There are three parts of MVC:
- Model: The Model is the backend. In a traditional web app, it would include some data store-most likely a database, classes for retrieving and updating data in the database. It can also include your service classes, which different clients (such as a Flash Player app, an HTMLweb app, or a Mobile app) can use to interact with the data. It is common belief that all heavy business logic should be implemented in the Model, although as view layers get more advanced, many are trying to find the balance between view logic and business logic.
- View: The view is the User Interface of your application. It is how your users will interact with the data. It might include the application pages in a web site, or screens in a Flex app.
- Controller: The Controller is what makes the application work. It takes requests from the view and sends it to the Model to retrieve data or perform business logic. It takes data returned from the model and sends it to the view for display.
In an ideal world, you would always implement your Model classes so that they know nothing about the View and your View classes so that they know nothing about the Model. There should be a clear distinction in responsibility. The controller makes the application by figuring out how to combine model data and business with the displays created in the view. For each model piece, and each view piece you want a clearly defined API which the controller can tie into.
Visually, I would diagram it like this:
So, a typical web application may work like this.
- A request comes to the controller. Let's pretend the request is to display a product's details.
- The controller says, for this request I need to get the product data from the model. So, it calls a method on the model to retrieve the product data.
- Then the controller says for this request I need to display this view. It loads up the view and passes the view the data it just got back from the model.
- Then the user can see the view and read about the product details.
To repeat it, the request comes into the controller, which then makes a request to the model, sending the appropriate data. The model sends the results back to the controller, which then sends it to the view and displays the view.
I have one extra line in the diagram, named interaction which the view makes requests to the controller. In a simple web page, like much of the Flextras site, the only interaction a user can perform is clicking a link or submitting a form. In either situation, this would send a brand new request to the controller, starting the process new. In a Flash or AJAX app you can make requests to the controller without starting a brand new request, but not for a simple web app. The updated diagram would look like this:
The focus of this approach is that you end up with a bunch of reusable model classes that can be easily reused with different views and different projects. You also have a bunch of view elements that can be easily reused with different model sets for different projects. As you develop this way, long term you build up a library of both model and view assets that you can throw together to make applications quicker.
I don't think I've said anything disputable yet, but feel free to take a quick breather before reading on.
Why does Model Glue Fail Me?
Model Glue is a Framework intended to help developers implement MVC in their own application. It, basically, is intended to act as the controller piece of your application. Instead of manually writing code to call methods or functions in your model, or to pass data to your view you create an XML file which tells the framework which methods to call in your model, and which views to load. Using this XML configuration file, the Model Glue framework figures out what to do and creates the view.
Unfortunately, the way Model Glue is setup, there is no way in the XML config file to define the data that is passed into the model, or the data that is passed into the view. Instead the classes of my model and view access Model Glue specific APIs to get the data they need. The modified diagram looks like this:
Let's look at our previous scenario, loading some product details:
- A request comes to the Model Glue index file.
- Based on the event name passed in, Model Glue gets the XML for that event. Based on that XML, it makes a call to a model file. The argument passed in is a special Model Glue object named Event.
- The function does it's work, and then sets values on the event argument, and returns that event argument to Model Glue
- Model Glue then checks to see what view page it should load and loads that page.
- The view calls a Model Glue API (ViewState) to get the data that should be returned from the .
Disclaimer: I am not an expert on Model Glue and have never explored the internals. If my assessment of what is happening is not entirely accurate; I apologize. I do not think it takes away from my larger point.
So, now the model classes are accessing Model Glue specific APIs through the single 'event' argument passed into the method. Instead of having a strictly defined API documenting the expected inputs-and outputs-of the method, we've simplified both to a single argument-the model glue event. The view class is just as bad. Instead of having a strictly defined API that documents the data needed for the view to display itself, we have no API. It is just references some 'global' variables defined in the Model Glue framework.
If you look closely at the image above, you'll see that the model is not sending data to the view; the view is reaching into Model Glue and pulling it out. The model has a similar problem, although not as obvious from the diagram.
The pieces of my application that were previously, beautifully encapsulated and primed for reuse, now have dependencies to the Model Glue framework and no strict API. This can't be right, can it?
If you're using Model Glue and still care about writing encapsulated code, you have to modify the original approach a bit, you have to add an extra layer of abstraction on both the view and the model, so that the nicely encapsulated and documented code is not explicitly calling into the model glue framework. These mediator classes would deal with the framework stuff, and protected your real view and model classes from the framework. It may look like this:
Of course, with this approach, you're now writing five files instead of 3, and the two mediator files appear to be doing the work that I'm using a framework to help solve.
Perhaps there is something I'm missing from the Model Glue approach. I want to use frameworks because they help me solve problems in my development. They help me write less code. They help me re-use more code. It seems my use of Model Glue has failed me on all of these accounts.
What am I missing?
An Alternate Approach to MVC
The more I think about my years of ColdFusion development, and my experience with Model Glue, the more I think that an alternate approach would better suit my development style. ColdFusion already, inherently provides all the tools I need built in to build encapsulated, reusable code. The three parts of MVC can sequence easily to different aspects of ColdFusion.
The model is your back end code, and with the model specifically, you want a defined API to access your data, or business logic. You want this API to be reusable across multiple front ends including HTML sites, or Flex applications, or mobile applications. ColdFusion Components (CFCs) are the best approach for this. CFCs are the ColdFusion version of a class, and allow for encapsulation of data and functionality. It wasn't until CFCs were introduced that ColdFusion started to feel like a real programming language to me.
It is easy to call CFCs from a CF Web based app, or from a Flex application with AMF. It is easy to expose a CFC method as a SOAP WebService or REST WebService. CFCs are the best resource for building the model. In all my Model Glue development, I've built my models entirely with CFCs. I'm given the impression other frameworks in the ColdFusion world use the same approach.
For the view, you want to define an API of inputs. You want to be able to reuse the code across multiple projects, or multiple times within a single project. I think there are two options to consider for creating views in ColdFusion. The first is to use a CFC designed for visual display. This is unusual in practice, but perfectly valid to create a CFC designed for visual display.
The second approach is to use ColdFusion custom tags. This is my preferred approach. I think custom tags are great for building out views. They give you the defined API and are easily called from the controller with specific data passed in. The only minor issue I see is that custom tags do not offer any of the advanced documentation facilities that a CFC does. There is no metadata, and you can't load it in a browser to see the documentation.
The controller should just be a CFM page. It is the entry point of your web user into the application, and can easily call methods on CFCs or call custom tags to prepare the view to the user. A CFM page could either represent a single page of the application, performing a single set of related actions. Or you could implement a page as a front controller, where the actions taken are decided upon by a URL variable.
Model Glue, and I believe many other ColdFusion frameworks, uses the second approach, where all requests are filtered through a single page, and the event variable determines which actions or to run.
I devised this approach a while ago and it is the natural extension of how I developed in the pre-CFC days. At one point I considered creating a presentation named "MVC Without a Framework" but I moved onto other things.
I wouldn't call this approach a framework by any stretch of the imagination, but more of a philosophy. It is simple, but I don't think development needs to be more complicated than that.
It's all your fault
You might be inclined to tell me that all the problems I had were my fault, or the fault of the developer I hired. The way we architected the application is at fault, and all our errors are because we didn't follow "best practices". You might be right, but it doesn't change the fact that I have a monolithic beast that I have to deal with.
Final Thoughts
I do want to tip my hat off to the folks behind Model Glue. This is not intended as an attack on them in any way. We share a similar goal of writing better code and creating maintainable applications. Unfortunately their hard work has missed the mark in my use case.
Part of the reason that I'm finally devoting time to write this up is that I'm going to start looking for a developer to do some more work on the site. It would be nice to say "Hey, this is part of what makes up my development philosophy." If you're interested drop me an e-mail
Aside from that, the reason I choose ColdFusion is because it makes hard development tasks easy. Sometimes I think an obsessive hard focus on frameworks and design patterns gets us away from the reason we use ColdFusion. It help makes us do our job quicker and easier.
Note: Extra special thanks to Alan Rother and Doug Reynolds for giving this a proof read for me and providing some constructive feedback.





My view pages also treat the event object as a variable scope: I retrieve the values I need out of the event object (the values returned from the model and added to the event object) and use them on the display page. It's not that different from how a non-MG view page would retrieve data from the session scope or from variables created by a previous file or function within the request.
I'm sorry if this post led you to believe I was never going to use the MVC design pattern again. That was clearly not the intent.
Me too!
Longer me-too post here: http://lagod.id.au/blog/?p=191
I deleted your duplicate. ;) Good catch my the misspelling of my first name, though. :ha, ha:
In terms of a view having dependencies to the model (or not) I Responded on your blog. But, The Flex Framework includes a whole library of UI Components that have no dependency to any model / backend classes. You are given complete flexibility.
HTML controls are, for the most part, built in the same paradigm.
A lot of what we do we can do because of the encapsulation of these UI pieces.
You may not care to optimize the views of your application for maximum reuse, which is a perfectly valid consideration based on your project's schedule and long term goals. Not everything needs to be encapsulate to the nth degree.
Second, I'd like to add on to Brian's comment above. He's correct, you don't need to tie your Model code to the framework in any way. Additionally, you can (and often should) break out most of the "business logic" into a Service Layer, which is also not tied to the framework (and is very reusable, just like the Model would be).
I build Model-Glue apps pretty often. To start my Model code out, I will typically use the Illudium Generator and just stick the Bean, DAO and/or Gateways in a /model folder (depending on which I'm using). I do the same to start my Service layer code. Sometimes I'll use the default Illudium template (which DOES tie the Model code to the Service Layer as a dependency, but still does NOT require any linking to Model-Glue, or another framework).
Then, all you have to do in your Model-Glue Controller is, take whatever variables were passed into the Controller, and hand them off to the Service Layer. Let the Service Layer return any sort of "status" message you want, usually including an error message if necessary. Then pass that info back into the Model-Glue event, and hand it off to whatever Event should be run next in your app (presumably to either display the error message, or move on to the next step in the app if there was no error).
So, the ONLY framework-specific code in that example is roughly 3 lines in the Controller method, like so:
1. Call my Service Layer, passing in the necessary variables (note, I am NOT passing "arguments.event" straight to the Service layer, as that would bind my Service layer to Model-Glue, which I don't want):
<cfset UserService.saveUser( aguments.event.getValue( "firstName" ), arguments.event.getValue( "lastName" ) ) /> (or whatever args your app needs)
2. Return any "status" message that my Service Layer gave me
<cfset status = UserService.saveUser( aguments.event.getValue( "firstName" ) .. ) />
3. If that message was an error, stuff the error message into a Model-Glue Event and do the "an error happened" event. (Or do the next step if there was no error).
<cfset status = UserService.saveUser( aguments.event.getValue( "firstName" ) .. ) />
<cfif status eq true >
<!--- load the "success / next step event" ) --->
<cfelse>
<!--- some error happened. punt. --->
<cfset event.setValue( "errorMessage", status.errorMessage ) />
</cfif>
That still leaves the "issue" of the Views being tied to Model-Glue. You can side-step this pretty easily too if you really wanted to. In a "typical" Model-Glue view, you might have something like so:
<cfset qryUsers = event.getValue( "qryUsers" ) />
...which grabs the Query "qryUsers" out of the Model-Glue framework (as it was probably created earlier by broadcasting an MG message called "needUsersList" or something smililar). And down below you'd have HTML to draw that list of Users to the screen.
You're right, that DOES tie the view to the framework, and requires modifying several files (View, Controller, ModelGlue.XML, and some sort of Model code and/or Service Layer) just to get that query. Well if you have Model-Glue up and running, unless you're on a REALLY old version of MG, you have ColdSpring too. So you could use a combination of ColdSpring and the Illudium templates and deal with it like so:
<cfset qryUsers = application.coldSpring.getBean( "UserGateway" ).getByAttributesQuery() />
...and that'd give you the same results as the event.getValue() line up above, except this line isn't tied to Model-Glue, and doesn't require modifying 5 files (though it does tie your app to ColdSpring, but that can be side-stepped too, if you really wanted to).
I don't think the MG die-hard folks like this approach much (though I may be mistaken) as the idea is that the Controller is used to manage ALL passing of data between the Model and the View. But really, for simple things like a "select * from Users" query that NEEDS to run for the View to function, I see no real down-side do slipping this short-cut into an app now and then.
Phew! That was a lot longer than I expected (I may re-post this on my own blog later. *g*).
hth
-nolan
PS. the Model-Glue forum on GoogleGroups is a great place to ask questions, big and small, new and old, about MG. Most get answered very quickly.
Personally my experience with MG is that it's been a real timesaver. And I'm not even really a MG developer any more, we use MachII where I work. But I think your complaints could be said about either framework... or just about any CF framework on the market right now. I'm very curious to hear more about your framework-less MCV approach!
I do have one bone of contention, though. You claim that ModelGlue is tied too much to the model. If this is indeed the case in the app you discuss, I would argue you are either a) using MG incorrectly or 2) your model architecture needs some work.
Last year I gave a presentation on separating out your model from your 'view' and 'controller' in applications. In this presentation I showed how a properly architected model can be dropped into any framework (or an app with no framework at all) without making ANY changes to the model. I wrote a sample app 4 times using 3 different community supported frameworks (ModelGlue, Framework/1 and ColdBox) as well as a 'homegrown' methodology, and each used the same model code. Not copies of the code, they all pointed to the same directory.
If anyone is interested, you can download the code from my blog, http://www.boyzoid.com/blog/index.cfm/2010/7/29/Mt...
The great thing about these discussions is they force me to refine my thinking. But this isn't really about M-G anymore, so I've responded in a new post: http://lagod.id.au/blog/?p=199
@Rachel,
Interesting that you found M-G to be a timesaver. My experience was exactly the opposite. Do you have a blog? It'd be great to hear exactly how and where you got the savings.
Re the framework-less approach: MVC is a simple concept that doesn't really need a framework (although framework support is nice for assistance with the mechanics of nesting views). What frameworks like M-G and MachII primarily provide is a structure that strongly directs one into a particular philosophy and style of programming, plus a grab-bag of other tools (e.g. ORM integration). But the MVC part is pretty minimal.
I think that perhaps model-glue has tried to over complicate things taking emphasis off the controller and shifting all its parts to different areas. Previously when I have used MVC most my code has ended up in the controllers, but in model-glue they are all practically empty.
You post has made things clear for me. Thanks
However, putting "most of your code" in controllers strikes me as "wrong", however it depends what code you're referring to. I wouldn't expect view code, nor major business logic to appear in the controller.
Since the Model Glue framework's purpose seems to be to 'replace' the controller portion of your app w/ am XML document, it does not surprise me that your controllers are doing very little.
Thanks for reading!