The Added Expense of Software That's Easy to Modify
In the Iron Man blog I talked about how the best and most useful tools often spring from small, simple ideas... and I mentioned how I feel the onTap framework is the only framework currently that addresses the increased cost of ownership for software that is described as "easy to modify". And I didn't give a thorough explanation of how that is, but I said I would come back to it and I didn't... So here's my expanded explanation.
Software that is "easy to modify" is often much more expensive than software that can't be changed. The reason for this is that web applications which advertise themselves as being "easy to modify" expect the person purchasing them to modify the existing code within the application. One example that was popular for a while in ColdFusion circles was the Able Commerce shopping cart. The company has been successful enough actually that there were a small handful of companies that made their money almost if not entirely from developing "plugins" for their shopping cart. So how were these plugins installed? I'm not sure if they involved additional configuration (I think likely), but I know at least that it involved unzipping the plugin files and copying them into the shopping cart directory, REPLACING existing files. So what happens if two of those plugins need to modify the same file? There's an installation order -- copy the files in the wrong order and you have to go back and start over. UGH! And this was a system that was phenomenally successful!
How about something even more successful? Dreamweaver. A while back I actually purchased a good book on creating Dreamweaver extensions, written by one of the other Team Macromedia members (I was on the team at the time). In it I learned how one of the big selling points for Dreamweaver was how customizable it was and that it was easy to customize because these customizations involved editing HTML and JavaScript, two things Dreamweaver users were already familiar with (and some XML I think). So today at the office I installed an updated version of Seapine's Surround SCM, which our company is using for version control (I'd rather SVN, but I'm not in chage there). The SCM client includes a Dreamweaver extension for integration, spiffy! And while I don't know if they made any changes to the extension I decided to go ahead and reinstall it anyway. It launches the Adobe Configuration Manager and what does it ask me? "This extension includes a file that already exists in Dreamweaver. Replacing this file may alter the way Dreamweaver behaves. Are you sure you want to replace this file?"
UGH! Not only are they (Adobe and/or Seapine, I can't tell), probably doing the same thing Able did, they're also stopping to ask me if I want to continue and without giving me any indication of what the replaced file affects! Bad user interaction design all the way around. Best case would be a system that made it unnecessary for them to ask me if I want to continue (a potentially anxiety producing question which I'm forced to answer with extremely vague and minimal information). It could have at least given me the file name and I could assess from looking at it if it had "seapine" or "surround" in the name that it was safe or that otherwise I might want to check my other extensions (I don't have any).
Which brings me to a solution for these problems. (Note use of the word "a" and not "the").
The onTap framework's core architecture actually grew out of a simple experiment. Like the simplicity of the stirrup it involved a very small amount of code. Now remember that this was on ColdFusion 5, so CFCs weren't yet available and what OO-style encapsulation features I used were merely emulated with functions and custom tags. I had discovered that I could get a list of the files in a particular directory (cfdirectory at first - later java), and loop over that list and include each file in order. What did this do for me? Well initially what it did for me was pretty small and not hugely useful. Files in the directory needed to be serially named, i.e. 100_setdefaults.cfm, 200_showheader.cfm, 300_showcontent.cfm, 400_showfooter.cfm. While it wasn't at that time the most miraculous thing in the world, it was still worlds better than the Able Commerce solution. I could create an application and plugin developers could add their code in the same directories without modifying any of my code. So when they coppied 250_pluginheader.cfm into the directory, it would simply be included between my header and content areas. And in retrospect, if there had been more widespread use of the table-less CSS layout designs that are so popular today, then this would have been much more useful even then.
Over time that small, simple experiment has evolved to become the core architecture of the onTap framework. Now when one of my plugins performs its installation, part of that involves moving files into the application, but, yet again, no files are modified (only moved). And this solution is even more powerful now because of the advent of the XHTML library and XSLT. It's become common in Fusebox applications and now in ColdBox applications to assign "exit fuseactions" (XFA) or "exit event handlers" (XEH). Likely people coming to onTap from either framework will end up using a similar convention, however, one of the nice things about the onTap framework is that if you use the XHTML library, you don't really have to. If you're writing a plugin that is designed to interact with someone else's application and you need a link or a form to target a different URL, you can change it with a few lines of very simple XSL, again without modifying any of the other person's code. Or if you're not comfortable with XSL, you can use CFML after the view has been declared like this: <cfset htlib.attribute(theForm,"action",newURL) />. So there are actually two different ways to customise the view.
This means that it should be fairly easy to install and test upgrades of the original application later and your company won't be stuck with an outdated version for years on end. When it's time to upgrade, you just make a copy of your working application, install the upgrade into your testing copy and then put it through its paces and make any minor tweaks that might be necessary for unexpected version-related issues.
This is one of the big things that none of the other frameworks as far as I know really allow. Plugin applications for a Fusebox 4 app could theoretically add circuits or even add fuseactions to existing circuits by manipulating the XML configuration files and writing over them... but then that means two things, 1) overwriting files and 2) much less precise and more difficult methods of modifying the view. You could of course easily add content to a content variable, say for example at the end of a menu, but inserting a new link in the middle of that menu would be a regex challenge. And in ColdBox it seems like this would be flatly outrageous to attempt, because instead of rewriting an XML file, your installer would have to rewrite the event methods in a handler CFC (likely using regular expressions).
The original author might have created a component object for managing the menu and registering new menu elements, although this will almost automatically reduce the flexibility of menu enhancements, because it will likely be bulky and complicated and limit you to whatever they thought might go in the menu. With an onTap framework menu, you can just <cfset htlib.childAdd(view.mainmenu,htlib.linkNew(text,url),3) /> and your new menu item is slotted into the 3rd place in the menu (and it doesn't limit you to links -- it could be a form or a button or a flash widget).
NOTE: I'm not using the word "plugin" to mean the same thing that frameworks generally mean when they say plugin. A "plugin" in ColdBox or Fusebox is something all-together different than a plugin in onTap -- a plugin in the onTap framework is much more like a browser extension like the Google toolbar or the WinAmp toolbar - a sub-application that provides utility to the end-user. This is also the way the word is used with Able Commerce plugins.
These features also reduced the number of templates I write -- I generally will only place one file in a given directory, the 100_default.cfm or 100_myplugin.cfm template in the /_local/ directory containing all the default content information for the current event. You might think of this like the body of a ColdBox handler method. Now the way the word plugin is used in other frameworks like ColdBox or Model-Glue does describe part of what this architecture allows. These other frameworks allow you to interject code before or after a handled event or before or after the request. The difference is that the interjection of code at those points is more complicated in those frameworks and it requires the person installing the plugin to edit code to make it work.
In other words, with most frameworks the core application must know about the plugin. In a properly architected onTap framework application, the core application doesn't need to know anything about its plugins or customizations - all it knows is that it's generating some content. If that content is later modified, so be it. (Though the plugin manager does provide a method of managing integration between them.) This makes it much more akin to (though not quite exactly the same thing as) Aspect Oriented Programming (AOP) and it's the final word on loose coupling in your controller.
The Members onTap plugin is a good example of this loose coupling. Members onTap provides two things - member management and a security framework. No part of your core application needs to have any information about the security framework in the Members onTap plugin to be protected by it. In other frameworks (at least those I've seen), typically there would have to be code somewhere specifying which circuits/handlers or which events/fuseactions are protected by the security framework. With Members onTap on the other hand, there's no need for the person writing a plugin to even care whether or not you're using a security framework. As an administrator you can apply security to any page in your application while the application itself is blissfully unaware that it's being secured.
Modifying existing templates means at a minimum increasing the difficulty involved in upgrading to a newer version later, and often to being stuck with an outdated version for years on end. So in an onTap application, modifying an existing template is a cardinal sin.

There are no comments for this entry.
[Add Comment]