Thinking About Code Objectly

I’m not talking about being unemotional about code, which would be “objectively”. No, “objectly,” I’m talking about code generation. When I first started writing Squidhead, I was writing procedural code to generate my code. After all, it’s tempting to think of it procedurally, as code tends to read from top to bottom. One of the breakthroughs for me was figuring out that most of the coding structures I was using can be expressed as objects. I mean the actual code text itself can be expressed as objects. In ColdFusion, this means a CFC.

Let me show you an example of what I’m talking about:

<!—************************************************—>

<!—create—>

<!—This function inserts a single comment record into the database.—>

<!—************************************************—>

<cffunction
access=“public”
name=“create”
output=“FALSE”
returntype=“numeric”
hint=“This function inserts a single comment record into the database.”
>

<cfargument
name=“body”
type=“string”
required=“FALSE”
default=“”
/>

<cfargument
name=“authorID”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“createdBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“updatedBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfset
var commentID = “”
/>

<cfset
var results = “”
/>

<cfstoredproc
procedure=“usp_comment_insert”
datasource=“#application.datasource#”
username=“#application.dbusername#”
password=“#application.dbpassword#”>

<cfprocparam
type=“OUT”
cfsqltype=“CF_SQL_INTEGER”
variable=“commentID”
dbvarname=“@commentID”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_LONGVARCHAR”
variable=“body”
dbvarname=“@body”
value=“#arguments.body#”
maxlength=“16”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“authorID”
dbvarname=“@authorID”
value=“#arguments.authorID#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“createdBy”
dbvarname=“@createdBy”
value=“#arguments.createdBy#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“updatedBy”
dbvarname=“@updatedBy”
value=“#arguments.updatedBy#”
maxlength=“4”
null=“NO”
/>

<cfprocresult
name=“results”
/>

</cfstoredproc>

<cfset results = commentID />

<cfreturn results />

</cffunction>

This is a basic insert function. We’ve all written this type of function as part of a CFC.

Let’s break this down into its properties:

Documentation

<!—********************************—>

<!—create—>

<!—This function inserts a single comment record into the database.—>

<!—********************************—>

Header

<cffunction
access=“public”
name=“create”
output=“FALSE”
returntype=“numeric”
hint=“This function inserts a single comment record into the database.”
>

Arguments

<cfargument
name=“body”
type=“string”
required=“FALSE”
default=“”
/>

<cfargument
name=“authorID”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“createdBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“updatedBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

Local Variables

<cfset
var commentID = “”
/>

<cfset
var results = “”
/>

Content

<cfstoredproc
procedure=“usp_comment_insert”
datasource=“#application.datasource#”
username=“#application.dbusername#”
password=“#application.dbpassword#”>

<cfprocparam
type=“OUT”
cfsqltype=“CF_SQL_INTEGER”
variable=“commentID”
dbvarname=“@commentID”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_LONGVARCHAR”
variable=“body”
dbvarname=“@body”
value=“#arguments.body#”
maxlength=“16”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“authorID”
dbvarname=“@authorID”
value=“#arguments.authorID#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“createdBy”
dbvarname=“@createdBy”
value=“#arguments.createdBy#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“updatedBy”
dbvarname=“@updatedBy”
value=“#arguments.updatedBy#”
maxlength=“4”
null=“NO”
/>

<cfprocresult
name=“results”
/>

</cfstoredproc>

<cfset results = commentID />

Results

<cfset results = commentID />

Footer

</cffunction>

Once you’ve established the structure of the CFC, you make these properties into variables. Anything that could be a list is actually an array. So arguments and local variables are actually an array of <cfargument> declarations, as is local variables. You write getter and setters. Actually I tend to write adders instead of setters as I’m just adding content to properties that grow. The getter that I write just concatenates all of the code and outputs it.

Here’s the code:

Function.cfc

You can even break it down even further. If you wanted, each <cfargument> could be an object with each attribute being a property. I didn’t go that far in Squidhead, but I did break the <cfstoredproc> declaration into an CFC.

This works very well for highly structured code, like <cfcomponents>’s , <cffunction>’s and <cfstoredproc>’s but it can be extended into less obviously structured code like custom tags. I was able to convert most of my procedural code creators to object oriented code creators.

So for whatever that’s worth, maybe this can help someone else out there.

4 thoughts on “Thinking About Code Objectly

  1. The only thing I don’t like about this implementation is that the formatting of the code ends up locked in Function.cfc. For me, this is similar to the debate over custom tags versus CFC’s for interface code.

    The code ends up being a formatted document that developers will eventually read. I’d be willing to trade performance to make that document format easier to change.

    I don’t like having to edit string concatenations buried in a cfc function to change the layout of the code, or to change the format of something usually personalized like comment flower boxes.

    Like

  2. That’s a good point, Dave, and that is why it does break down the less structured the resulting code is. I’d argue that with functions, storedproc’s, and cfc’s there are a finite set of permutations because there are a finite set of attributes for the code structures. You may quibble over formatting or order of calls, but I think that tradeoff is worth it. With custom tags and cfml templates, one could argue that it isn’t.

    Like

  3. His decision to replica handbags sign elsewhere, though, limits the wholesale handbags Red Sox’s search for a shortstop. The free agent market at the position is louis vuitton handbags extremely weak, and, barring a trade, the prospects for a replacement are pretty bleak

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s