CF9 Coding Best Practices
- Posted by bcarr on 04.06.2010 12:13 PM | 1171 comments
We recently hired on a new and very capable CF developer at work and part of the preparation required to ready the team for a new addition is to ensure our project documentation is current and understandable. No sooner did I undertake this small task than did I realize I would have to make some updates and adjustments to our documented coding standards. As I sifted through the information I couldn't help but feel compelled to share some of the more prominent points with the rest of the CF community in order to garner some critical review.
So here they are - not in their entirety, but a few. I've also provided some enhanced explanations as well. If you feel I'm missing something here or am off track in some way - let your voice be heard!
Ditch the Tags
Not in every case to be clear, but when working with components and interfaces it would be well with you to say goodbye to them. Less is definitely more here - why write more code when you can accomplish the same exact task with less? The obvious answer to that question is 42.
But beyond the empirical finger-saving efficiency that accompanies script, there are more subtle but just as important psychological benefits to be realized here. That's right - youth who grow up using CF script in this manner are statistically less likely to abuse small animals. There's no denying that the tag-based API for CF has been the proverbial "special sauce" for the technology since it's inception, so this may be a bitter pill to swallow for some. Let me say this first before I make my case - I genuinely love working with ColdFusion! However nowadays the CFML "Tag" syntax is much more likely to invoke *sighs* of dissatisfaction or even worse disrespectful laughter from new or would-be CF programmers when comparing it to other languages. I've dealt with both reactions on more than one occasion. This unfortunate snap-judgement can many times deter developers from giving CF a fair look and leave undiscovered it's elegant simplicity and raw power. With the ability now to create CFC's entirely with CF script syntax (without the need to wrap content in tags) the language conveys a much more serious OO-capable "looking" language vis-a-vis this succinct syntax turning this;
<cfcomponent> <cfproperty name="firstName" type="string" /> <cfproperty name="middleInitial" type="string" /> <cfproperty name="lastName" type="string" /> <cffunction name="init" access="public" returntype="Person"> <cfreturn this /> </cffunction> <cffunction name="setFullName" access="public" returntype="void"> <cfargument name="firstName" type="string" required="true" /> <cfargument name="lastName" type="string" required="true" /> <cfargument name="middleInitial" type="string" required="false" default="" /> <cfset variables.firstName = arguments.firstName /> <cfset variables.lastName = arguments.lastName /> <cfset variables.middleInitial = arguments.middleInitial /> </cffunction> </cfcomponent>
Into this;
component {
property string firstName;
property string lastName;
property string middleInitial;
public Person function init() {
return this;
}
public void function setFullName(required string firstName,
required string lastName, string middleInitial="") {
variables.firstName = arguments.firstName;
variables.lastName = arguments.lastName;
variables.middleInitial = arguments.middleInitial;
}
}
Now that I've gotten that out of the way it's very important to say that I believe tags have their place, although not in CFC's but instead in other familiar places - carefully employed in .cfm pages responsible for view rendering. Leave them out of the realm of OO constructs.
Use Properties for Implicit Getters / Setters
Prior to CF 9 I strongly questioned the necessity for the <cfproperty /> tag. But now with the introduction of the implicit getters and setters functionality - declared properties should be commonplace in your CFC's. Coupled with the component-level "accessors" attribute, properties become a very effective time-saver by generating an associated getter and setter for the property data-type "implicitly". This means that although the mutators are not explicitly defined in your CFC, they exist on any object instantiated from it. In a word - awesome.
Before;
component {
public Person function init() {
return this;
}
public void function setFirstName(required string firstName) {
variables.firstName = arguments.firstName;
}
public void function getFirstName() {
return variables.firstName;
}
public void function setLastName(required string lastName) {
variables.lastName = arguments.lastName;
}
public void function getLastName() {
return variables.lastName;
}
}
After;
component accessors="true" {
property string firstName;
property string lastName;
public Person function init() {
return this;
}
}
"this" is very, very bad
When working with CFC's using the "this" scope to declare instance variables can be very tempting, and bad. Resist the temptation to participate in this egregious violation of encapsulation. Any serious developer working with your code will have suffered the same as if they had just witnessed a trenchoat flashing - "I don't want to see those variables dangling in the breeze like that!". Make those variables private please by establishing them in the "variables" scope, then provided accessor methods only when necessary.
Use Type-Safe Arrays
This is another highly under-utilized and useful CF approach to ensure type-safety. When creating functions that intend on returning an array of similar custom types, don't specify the return-type for the method as "array". Instead use array notation for a custom type, like so;
public User[] function getUsers() {
return variables.users;
}
Again, this list is nowhere near comprehensive. There are many more approaches I would like to address but wanted to keep this to the point. As a community it's important we continue to explore and share effective CF development techniques. Until next time!
which make them, appear to be severely very good and heat. Moncler Womens Coats Your Type Moncler Nantes,One of the best attenuateg abender the this forged i.e.