What ColdFusion Teaches Us About The Ultimate "Roll Your Own" Solution
A while back, Rebecca Murphey started posting some interesting thoughts about what enterprise Javascript applications are and how they should be structured. One of her posts that really got me thinking was one titled, "On Rolling Your Own". In that particular post (with reference to a few others), Rebecca questions the logistics of rolling your own application platform by piecing together bits from a variety of different libraries. While I don't want to argue with what she was saying, the points she raised got me thinking about ColdFusion; specifically, I started to wonder if ColdFusion was the ultimate "roll your own" solution (and what that teaches us about software development)?
If you ever look at the ColdFusion 9 End User License Agreement, you'll see that there's a whole lot more to ColdFusion that just ColdFusion. Skim the agreement and you'll find that under the ColdFusion covers, the application platform contains the following 3rd party libraries:
- Solr
- ehcache
- Lucene
- Open Office XML Support
- POI
- XMLBeans
- Something from Apache Foundation
- JasperReports
- Hibernate
- Something from DataDirect Technologies
- Something from Google
- Something from GreenPoint
- Servlet Libraries
- WebChart3D Enterprise
- Parser Libraries
- Java DOM libraries
- Something from ImageMagik
- Something from International Business Machines Corp
- Something from Intrinsyc Software
- Something from JNBridge
- FCKEditor
- Something from Logica Mobile Networks
- iText
- DOM4J
- Rhino Javascript Interpretor
- Something from ObjectWeb Consortium
- OpenSymphony
- Something from RSA Data Security
- Something from SUN Micro Systems
- GIF
- HTTPClient
- Something from the W3C
- Something from Yahoo!
NOTE: When I say "something from", it's because the EULA doesn't state what specific piece of software was being provided from the given organization.
That's a lot of stuff! There's no doubt that Allaire, Macromedia, and Adobe built the vast majority of the ColdFusion application platform; but, when you look at the 3rd party list of software, it's clear that a lot of functionality in the language comes from different packages that have been pieced together. Add to that the fact that ColdFusion is built on top of Java and you quickly realize that what you get is waaaaay more than what you actually see.
Now, no one would look at ColdFusion and think of it as a, "roll your own," solution. Anyone who uses ColdFusion knows just how powerful and comprehensive it is. In fact, with more than 125,000 ColdFusion servers deployed, ColdFusion is one of the most widely adopted web technologies in the industry.
So, how can ColdFusion be both an enterprise platform and a composition of so many different libraries? I think it comes down to encapsulation: ColdFusion never comes across as a "roll your own" solution because it presents itself a single, unified platform that successfully encapsulates its complex, multi-part implementation.
What does this teach us about our own application development practices? In order to create our own robust platforms that are at the same time unified, usable, pluggable, and maintainable, we have to create a layer of abstraction between what the programmer sees and what the underlying code does. It is this separation - this API (Application Programming Interface) - that differentiates "platforms" from "roll your own" solutions.
In the world of Javascript applications (which is where this conversation originated), I suppose it means that no one would ever directly invoke jQuery or jQuery UI or Dojo or MooTools or Mustache or any of the many web development libraries out there; rather, programmers would use your platform API, which, may in turn, use the jQuery or Dojo or MooTool (etc.) libraries internally. And, any time you wanted to add functionality to your platform in the way of a 3rd party library (ex. custom font rendering), you would have to provide the functionality by way of a core API augmentation that encapsulates the use of the new library.
Now, I'm not really saying that this approach is feasible for any given developer starting a new web application project. But, I think there is some very interesting theory to be taken from the architecture behind application platform behemoths like ColdFusion. If nothing else, it teaches us that impression is heavily dependent on presentation and not on implementation.
Reader Comments
Ben,
I absolutely agree. One of the nice things about this strategy is that it allows you to change our your underlying libraries if you ever need to do so.
ColdFusion, for example, has done this (though not completely transparently) by opening up the option to have CFSEARCH use Solr instead of Verity.
I have some custom tags that currently use qForms under the hood. While I like qForms, I also like that I can switch the underlying JS API to jQuery later if I want to do so.
Obviously another advantage of this approach is that you can change your underlying libraries without changing your API, e.g. swapping out Verity for Lucene. And hence the other CFML engines available. Another great benefit to CFML, portability.
Also we should be reminded that being great is one thing. To create something great, you need to collaborate.
@Steve - snap, great minds think alike, fools never differ.
Good application developers know how to write code. Great application developers know how to find code that already works and then adapt it to do what they need.
Who in their right mind would want to write every single line of code for an application by hand?
@Rick,
I hope this isn't too off topic but, is this true? I've only been programming in the workplace for 4 years. I often look at what others have done and adapt it to my particular needs. Often times, I've wondered if this was normal of developers or if it could be seen as a crutch of mine. I figured why reinvent the wheel, but I always feel slightly guilty about it also.
@Jacob -- absolutely. The trick is knowing when it'll take less time to do it yourself than wedge someone else's oval shaped application into your round hole.
@Steve, @Darren,
Excellent point! Keeping a platform API (any API at that matter) allows for a much easier time to swap underlying libraries, or even to build your own.
@Rick, @Jacob, @JC,
I think there's merit to both approaches and part of the magic is figuring out which action is appropriate. There are definitely things when the underlying code is so tweaked and optimized (ie. jQuery), that there's no way I could begin to write a library that good.
However, there are many times where I come across a wrapper for something such as a CFC that wraps an API, where I simply would want to implement it different or change some of the fundamental assumptions (ex. should value XYZ be passed in on each method call or only with init()). In that case, I'll write my own wrapper, learning from the other one as needed.
So, as @JC put it, the trick is knowing "when".
This is how good enterprise software and good enterprise architecture is built. In addition to the time factor and the abstraction potential, the most compelling reason I've ever found to incorporate existing solutions is that the problems they often solve are non-trivial. The more you can let someone else worry about specific, vertical problems, the more time you have to solve your own integration problems.
Simply put, creating a search engine (as one example) is _hard_. Why do I want to take on that vertical and all of its current and future challenges if I can ethically apply an existing solution from a group "dedicated" to supporting it?
The key, of course, is a good API. As the beneficiary of these vertical solutions, you need to be able to wire everything together to create an effective solution of your own.
Which means, of course, that one skill needed by a developer is the ability to analyze a problem in terms of tasks that may already have been accomplished - like the famous joke about the mathematician turned fireman.
What, you haven't heard about the mathematician who applied for a job at the fire department?
It seems he went for an interview with the fire chief. The fire chief said, "OK, to test your ideas on fire fighting, here's a story. You're walking down an alley behind a store, and there's an open dumpster. You see trash burning in it. What do you do?"
The mathematician said, "I run into the store, grab a fire extinguisher, and put the fire out!"
"Great!" said the fire chief. "Now, suppose you're walking down the alley, you see the open dumpster, and there's no fire in it. What do you do?"
"Drop a lighted match in," said the mathematician.
"What?!" exclaimed the fire chief. "Why?"
"Well," explained the mathematician, "if I start a fire in the dumpster, I can reduce the situation to a previously solved problem."
@Rob,
Search is such a great example of this, not only because it really does solve such a hard problem, but also because ColdFusion has actually switched the underlying search engine without disrupting the API (as far as I know).
@Matt,
I actually laughed out loud at that :)
@Ben,
Thanks! But it does show off my point, which is that a developer has to be able to think about a problem in terms of related problems that have already been dealt with "well enough".
@Matt,
I think you make a good point.
Another issue is "How much will you learn by developing a solution for yourself?" I have been accused in the past of developing my own solution while not taking advantage of a "pre-made" solution in the past that was sub-optimum.
Usually, it is due to my finding the solution lacking, baffling, or inelegant. Sometimes it amounts to refusing to accept restrictions of the available code.
If something is available to solve a problem and the quality of the solution is known, I would have no problem using it. Understanding the quality is something that can't always be determined.
Sometimes hiding the components behind can be a major pain in the ass. Just look at the CF Webservice "module" which is based on the Axis framework.
The Coldfusion does really a lot in the background, it converts the datatypes, complex objects, creates stubs with wsdl2java, compiles them, you get a nice cf object with methods.
Everything peachy until it fails for some reason (usually a wierd bug in Axis), and then you have almost zero possibilities to debug it (or fix it for that matter).
Recently we had to call webservices with cfhttp (your recipe: 1809-Making-SOAP-Web-Service-Requests-With-ColdFusion-And-CFHTTP.htm) as a workaround, because Axis was throwing tantrums.
@Roger,
I think you and I roll the same way; often times, when you rebuild something that's been done before, you walk away with a much better understanding of what is actual going on. Then, you can start to leverage the code more effectively (hopefully). Of couse, this is only with things that I *can* actually rebuild in an elegant way; I certainly have nothing aginst using things that are better.
@Nelle,
Yeah, very true - SOAP packaging in ColdFusion can be especially painful. But, keep in mind that even when you have to fall back to CFHTTP calls, the CFHTTP tag is still encapsulating some underlying HTTP client. At the end of the day, ColdFusion is still doing a beautiful job of encapsulating the underlying implementation. Such an awesome language (and they're only making it better with each release).