home Links Articles Books Past Meetings Photos SiteMap
The MDCFUG is sponsored by TeraTech. Visit us at www.TeraTech.com

Please send
comments/questions to

michael@
teratech.com

 

ColdFusion MX Coding Guidelines - Good Practice

Release 3.0.2 (10/17/2003)

« Structure: Application, Component, Tag etc | Contents | Database Conventions »

Good Practice

This section provides some hints and tips that are considered "good practice".

Booleans

Booleans are always true or false, conditions are also true or false - do not test a boolean expression against a value, just test the expression:

<cfif boolVar is "true">     <!--- BAD! --->

<cfif boolVar is "false">    <!--- BAD! --->

<cfif boolVar>               <!--- good --->
<cfif not boolVar>           <!--- good --->

cfswitch/cfcase

Instead of cascading cfelseif blocks, when you are branching on the value of a single expression, use cfswitch and cfcase instead:

<!--- bad: --->
<cfif expr eq "Value A">

    ...
<cfelseif expr eq "Value B">
    ...
<cfelse>
    ...
</cfif>

<!--- good: --->
<cfswitch expression="expr">

    <cfcase value="Value A">
        ...
    <cfcase>
    <cfcase value="Value B">
        ...
    </cfcase>
    <cfdefaultcase>

        ...
    </cfdefaultcase>
</cfswitch>

Components & cfargument

ColdFusion MX does not require that you use cfargument tags but they provide validation (type safety) and act as additional documentation - always provide a cfargument tag for each named argument your function expects and follow these rules:

  • Always specify the type= attribute in your cfargument tags. Try to avoid using type="any".
  • Always specify the required= attribute in your cfargument tags.
  • If an argument is required, do not specify a default= attribute.
  • If an argument is not required, you may specify a default= attribute (but remember that you will not be able to tell the difference between the caller omitting that argument and the caller providing that same default value as an argument).
  • If you need to detect whether a non-required argument was provided, do not specify default= but instead use structKeyExists(arguments,"argName") in the function body.

Components & cfproperty

Be aware that the cfproperty tag is of limited use - it does only two things:

  1. It provides additional type validation for Web Service return types.
  2. It provides a way to add metadata to components.

In general, cfproperty should not be used - it does not provide type checking for instance data (in general) and it does not provide default values for instance data so its presence can be misleading rather than helpful.

If you really are returning a component type from a Web Service and want the public data members of that component to be type-checked at runtime, then cfproperty can be useful.

If you are creating a metadata-driven system, then cfproperty can be useful (although dynamic systems driven by component metadata tend not to scale well!).

Components & Constructors

All components should define a method called init() that initializes the instance, even if the body of the method is empty, i.e., the initialization doesn't do anything. This makes usage of components consistent since you are guaranteed to be able to call init() on any component instance, just as you can for Java objects created within ColdFusion. The method should have a return type that matches the component and it should return this so that the following construct is always legal:

<cfset obj = createObject("component","util.lib.thing").init() />

This matches the way that createObject().init() behaves for Java objects - init() returns the fully initialized Java object.

The util.lib.thing CFC would have a method that looks like:

<cffunction name="init" access="public" returntype="util.lib.thing">

    ...
    <cfreturn this />
</cffunction>

If your component extends another component, your init() method should begin with a call to super.init() to initialize the base component.

Note: The call to super.init() must use positional arguments - the argumentCollection= calling style does not work with methods called via super.

Note: There is a notable exception to this guideline - when you are extending components in Mach II (listeners, plugins, event filters), instead of defining a method called init(), you define a method called configure() (which does not return anything - configure() has returnType="void"). This is because the framework itself uses init() for its own initialization and provides configure(), which it automatically calls for you once the framework has been initialized, so that you do not have to worry about any initialization arguments that the framework requires.

Custom Tags

Custom tags should be organized into related group by using a meaningful directory tree under the Custom Tag Path (defined in the ColdFusion Administrator). This makes it easier to use cfimport to access specific groups of custom tags.

All custom tags should anticipate being executed in both start mode and end mode, i.e., they should be structured as follows:

<cfif thisTag.executionMode is "start">

    ...
<cfelse> <!--- thisTag.executionMode is "end" --->
    ...
</cfif>

If the custom tag is a simple one, i.e., it doesn't process a tag body, then the cfelse section should be empty (and cfelse can be omitted). Do not put spurious complaints in the cfelse section about being called twice!

Do not hardcode a result variable in a custom tag, e.g., caller.result. Instead, use a resultVariable attribute and return results by setting the specified variable, i.e., caller[attributes.resultVariable]. This is more flexible and also reduces coupling between a custom tag and its calling page.

« Structure: Application, Component, Tag etc | Contents | Database Conventions »



No comments found

Source: http://livedocs.macromedia.com/wtg/public/coding_standards/goodpractice.html


Home | Links | Articles | Past Meetings | Meeting Photos | Site Map
About MDCFUG | Join | Mailing List |Forums | Directions |Suggestions | Quotes | Newbie Tips
TOP

Copyright © 1997-2024, Maryland Cold Fusion User Group. All rights reserved.
< >