Categories
Contact Doug!
Learn About Doug!
View Doug Boude's online resume
updated 11/18/2009

View Doug Boude's profile on LinkedIn
Link to me!

Follow Doug Boude on Twitter
Follow me!

Be Doug's friend on Facebook
Befriend me!
(I promise not to follow you home)
OO Lexicon
Chat with Doug!
Recent Entries
You may also be interested in...
Web Hosting

<< May, 2013 >>
SMTWTFS
1234
567891011
12131415161718
19202122232425
262728293031
Search Blog

Recent Comments
Re: Disappearing IE Popup Window During Save/Open Dialog (by LZ at 4/20 7:58 AM)
Re: Create Dynamic WHERE Clauses in PHP (by pooja at 3/20 7:29 AM)
Re: Just What IS a 'Service Layer', Anyway? (by EugenK at 3/07 7:56 PM)
Re: Using Google as your CF Mail Server (by 5starwebteam.com at 2/25 1:27 AM)
Re: Why Provide for Service layer objects in CFWheels? (by Steven Benjamin at 1/25 11:43 AM)
Re: What is an 'Advanced' Coldfusion Developer? (by ColdFusion Developer at 12/24 5:14 AM)
Re: Equivalent of SQL "TOP X" in Oracle (by Ashenafi Desalegn at 12/06 5:29 AM)
Re: PHP Export to Excel Snippet (by serene at 12/05 1:44 AM)
Re: Just What Is 'Application Logic', Anyway? (by Arif at 11/13 8:06 AM)
Re: Hosts File Changes Not Acknowledged on Vista 64 (by Aaron at 10/22 2:31 PM)
Re: PHP Export to Excel Snippet (by Jafar Shah at 10/10 4:28 AM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by Chenelle S at 10/04 12:53 PM)
Re: PHP Export to Excel Snippet (by Kilo at 9/26 5:20 PM)
Re: Porting Coldfusion Code to Mura (by tariq at 9/03 9:51 AM)
Re: Just What IS a 'Service Layer', Anyway? (by James at 8/27 4:06 PM)
Re: Calculating Business Hours (by helen at 8/14 2:54 AM)
Re: What IS 'Business Logic', Anyway? (by dougboude at 8/06 11:30 AM)
Re: What IS 'Business Logic', Anyway? (by Adrianne at 8/06 10:29 AM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by dougboude at 8/04 4:39 PM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by Lola LB at 8/04 7:43 AM)
Archives
Photo Albums
Funnies (5)
Family (3)
RSS

Powered by
BlogCFM v1.11

19 April 2011
Picking Up Where Interfaces Fail
Interface.CFC

What Is An Interface?

Interfaces in ColdFusion are something that makes most of us turn our heads sideways and give the two dollar look. Any of us who didn't come from other languages before ColdFusion probably hadn't heard of them, and since they were introduced into CF, the majority of us haven't taken the time to even understand their purpose, let alone actually use them for anything. Myself, I did take the time to know what they were for (in a ColdFusion context anyway), but even so had never found a single solitary use case for them...until recently.

For the record and to give the rest of this post context, let me share my understanding of what interfaces do for us in ColdFusion. In a nutshell, they act as validators for our CFCs. That is, by "implementing" an interface within a component (<cfcomponent implements="myInterface"....>), we are forced to adhere to rules we laid down beforehand for the functions we will write in the future, and we'll be stopped dead in our tracks if we violate any of those rules. Rules such as  what arguments a function must minimally have, what the returntype of a function should be, and other criteria that interfaces allow us to specify.

My Use Case

I have recently written a small library called JBase that is a virtual relational database. Two pieces of functionality that JBase sports, which I factored out into their own components, are data formatting and validation. Now, knowing full well that I haven't anticipated every possible formatting or validation need, I created those components in such a way that they can be easily customized by the developer, AS LONG AS CERTAIN RULES ARE FOLLOWED when writing the custom functions.

I documented what those rules are very thoroughly, as well as placing them into the CFC itself as comments. But, I really wanted to be able to make CERTAIN that all customized functions followed my rules. Now this, you might be saying to yourself, is a perfect use of ColdFusion interfaces! And you would be so very right if it weren't for a couple of teeny weeny challenges, challenges that caused ColdFusion interfaces to utterly fail in this scenario.

1) CF Interfaces (as it is in all languages to the best of my knowledge) require that you EXPLICITLY indicate the name of the function you want to police - but I have no idea what my developers will name their custom functions! As long as they follow a naming convention of "format[whatever]" or "validate[whatever]", the function has a valid name according to my rules.

2) ColdFusion interfaces do not allow me to police functions that are designated as private. Why, I'm not sure, but since one of my rules is that custom functions MUST be private, this was also a fail. What to do, what to do?

Write my own interface component.

What I needed was something I could transparently apply to a component or chain of components (if one extended the other to infinity) that would inspect all of the methods and ensure those whose names matched a pre-defined pattern also adhered to other applicable rules. I called it, strangely enough, "Interface.cfc". Interface.cfc leverages a "rules" configuration array that it uses to analyze the methods, public AND private, within a component or component chain that can be n levels deep. It allows me to provide a regular expression describing function names, and when it encounters a function whose name matches the regex, it then analyzes the function based on the rules associated with that regex. Here's an example rules config array:

<cfscript>
  stRules = [
  {
   name = "^format(?!Value).+?",
   args = {
    targetValue = {
     type = "string",
     required = "true"
    }
   },
   access = "private",
   returntype = "string"
  },
  {
   name = "^validate(?!Value).+?",
   args = {
    targetValue = {
     type = "string",
     required = "true"
    }
   },
   access = "private",
   returntype = "boolean"
  }
 ];
 return stRules;
</cfscript>

 

Allow me to share a short list of Interface.cfc's highlights:

  1. Very non-intrusive. Simply extend Interface.cfc within a component or within the most base component of any heredity chain;
  2. Rather than die on the first error encountered, Interface.cfc will analyze the entire function collection at once and throw a comprehensive error detailing EVERYTHING it found in violation of the rules;
  3. The rules is an easy to read array that is self-explanatory and highly expandable.
  4. Rules are triggered when a function name matches a regular expression in the "name" key for a given rule set.

 

 

 

That's it! Let me show you how to use it and then what the results look like.

Picture If You Will...

Here is a rough diagram of the components that comprise the JBase relational database library. I've circled the customizable components in red:

Here is the same diagram showing interface.cfc implemented to ensure that all of the rules I lovingly outlined in the documentation are actually adhered to :) :

In this diagram, the components circled in red are those who will be validated by Interface.cfc. If we had three or four or n components in the inheritance chain, ALL of them would be subject to Interface.CFC's scrutiny. (note: the level at which Interface.CFC's functionality is triggered does allow one to control "how high" up the chain validation will crawl. The level at which "validateInterface()" is executed is where validation begins to cascade downward. Typically, you will execute validateInterface() at the topmost level component in the chain.)

To use Interface.CFC, follow these simple steps:

1. Create the rules array within the getRules method of Interface.CFC;
2. Make the most base component in the chain (or the component being validated, if there's only one) extend Interface.CFC (<component extends="Interface"....>")
3. Execute the "validateInterface()" method in the pseudo-constructor area of the topmost component that is to be validated
liks so:

<cfcomponent extends="myBaseComponent">
 <cfset validateInterface() />
 
 <cffunction name="init" ....</cffunction>
 ....
</cfcomponent>

 

 

For demonstration purposes, I have chained together (via the "extends" attribute) three components with the most base of them extending Interface.CFC. My rules are defined as in the rules example above. I purposefully coded in several errors. When I attempt to instantiate the topmost component, here is a screenshot of the results:

That's it! I'm extremely pleased with the results.

You can grab Interface.cfc here. Get Interface.cfc from Github at: git://github.com/dougboude/interface.git  View the awesome API documentation here.

And Boyan Kostadinov (@boyank), my .NET evangelist buddy, time to eat a little crow pie my friend. I don't UNDERSTAND interfaces??? Wrong, my man. Dead wrong. Contrary to the beliefs that keep some programmers of other languages thinking highly of themselves, this stuff just ain't all that challenging to comprehend once you weed through all the highfalutin lingo, acronyms, jargon, and fluff. Literally, I can teach this stuff to my 4 year old (and have!). ;) Love you buddy.




Posted by dougboude at 12:18 PM | PRINT THIS POST! |Link | 3 comments
Subscription Options

You are not logged in, so your subscription status for this entry is unknown. You can login or register here.

Re: Picking Up Where Interfaces Fail
"Why, I'm not sure" you can't police private variables ? Because you shouldn't care about the internal workings of an object. That's what private means.

"follow a naming convention of "format[whatever]" or "validate[whatever]", the function has a valid name" Instead, you could have 'format' and 'validate' interface, which defines a public function called 'justDoIt()' ? If the 'whatever' is important, then the interface should define public get/set pairs for it.

PS foo+bar@domain.com is a perfectly valid email address, but your page doesn't allow it :-)
Posted by Tom on April 20, 2011 at 9:09 AM

Re: Picking Up Where Interfaces Fail
Very interesting approach Doug. I actually recently ran into a perfect use case for coldfusion interfaces. We are developing an open source eCommerce system called Slatwall for mura. We wanted to allow for developers to add their own custom payment gateways, and shipping services. So we used an interface to specify the types of functions that required, and the response beans that they need to pass back. Then on application load we loop through all the folders in a particular directory looking for a Service.cfc that implements our interface. Any of them that do we display in the UI as a service that is available and configurable.

We didn't really run into the same needs that you did because the only thing that we wanted to enforce were the public methods because those are the methods that the system ends up "interfacing" with.

Anyway, just thought a use case might give some insights.
Posted by Greg Moser on April 20, 2011 at 11:58 AM

Re: Picking Up Where Interfaces Fail
@Tom, private methods are just as valid a part of an interface as public; they just happen to be an INTERNAL interface. In my architecture where customization is allowed in the topmost component of a short chain, the "rules" are that the custom methods must be private due to the fact that the "public" interface consists solely of the methods "validateValue" and "formatValue", with the two arguments passed in to each being the type of validation/formatting, and the value to be validated/formatted. It makes the API SUPER SIMPLE. Yet, at the same time, I STILL have the need to know that my users are writing their custom methods correctly, hence my use case. I suppose I could, as you're indirectly suggesting, just trust them to do it right and, if they don't, allow the app to catch and throw them an error at the point where they try to call their invalidly written method. Nah. I think I'll perform all validation during instantiation. ;)
Posted by dougboude on April 21, 2011 at 11:01 AM

Name:   Required
Email:   Required your email address will not be publicly displayed.

Want to receive notifications when new comments are added? Login/Register for an account.

Time to take the Turing Test!!!

Two plus Two equals
Type in the answer to the question you see above:

Your comment:

Sorry, no HTML allowed!