Sign Doug's SOTR Petition!

Sign Doug's petition to his boss and help send him to Scotch on the Rocks in 2012!
Recent Entries
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!
NO MORE CAREER
POLITICIANS!
Get Out Of Our House: Replacing congress with TRUE citizens!
You may also be interested in...
Web Hosting
best web hosting - top web hosting sites, thetop10bestwebhosting.com

Czech your Page Rank!
Check Page Rank of any web site pages instantly:
This free page rank checking tool is powered by Page Rank Checker service
Surf's Up!
Visit Egosurf.org and massage YOUR web ego!
My Score: 9,001
Doug's Books

Read (and recommend)

  • Men are from Mars, Women are from Venus
  • The Wisdom of Crowds: Why the Many Are Smarter Than the Few and How Collective Wisdom Shapes Business, Economies, Societies and Nations
  • Blink: The Power of Thinking Without Thinking
  • Head First Design Patterns
  • Transact-SQL Programming
  • What's So Amazing About Grace?
  • Just So Stories (Rudyard Kipling collection)

Reading

  • Prayer: Does it Make Any Difference?
  • Data Mining (Practical Machine Learning Tools and Techniques)
<< February, 2012 >>
SMTWTFS
1234
567891011
12131415161718
19202122232425
26272829
Search Blog

Recent Comments
Re: Why I Hate ORMs (a solicited rant) (by aris setyawan at 2/20 2:48 AM)
Re: Element.show/hide anomoly in Prototype (by Jens at 2/19 6:30 AM)
Re: My Twelve Steps to a Coldbox App (by Francesco at 2/17 12:06 AM)
Re: SQL Forward Engineering with Visio 2003 Professional (by Leo at 2/13 10:55 AM)
Re: Basic Ajax Select List Filter in PHP (by opineemia at 2/02 8:47 PM)
Re: PHP vs COLDFUSION (by dougboude at 1/24 9:47 AM)
Re: PHP vs COLDFUSION (by WhatTheHeck at 1/23 7:03 PM)
Re: Recursive Functions in ColdFusion (by Marty McGee at 1/22 1:01 PM)
Re: SQL Forward Engineering with Visio 2003 Professional (by Rama at 1/10 11:05 AM)
Re: PHP Export to Excel Snippet (by rasha at 1/10 1:55 AM)
Re: Fredrick "French" Fry (by Picky eater at 1/09 2:21 PM)
Re: Disappearing IE Popup Window During Save/Open Dialog (by Vivekanand at 1/06 12:51 AM)
Re: Just What IS a 'Service Layer', Anyway? (by Ashishkumar Haldar at 1/05 7:49 AM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by ranjit sachin at 12/20 6:22 AM)
Re: Recursive Functions in ColdFusion (by Jason at 12/15 12:13 PM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by kt at 12/08 3:47 AM)
Re: PayPal IPN Coldfusion CFC (by Guest at 11/28 6:11 PM)
Re: SQL Forward Engineering with Visio 2003 Professional (by freddy villamil at 11/09 2:49 PM)
Re: Finally Found a Use for CFTHREAD (by criclebrava at 11/09 1:23 PM)
Re: Finally Found a Use for CFTHREAD (by assisisowsfub at 11/07 10:37 PM)
Categories
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!!!

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

Your comment:

Sorry, no HTML allowed!