How many times did you write the accessor methods (better known as getters and setters) for the fields of your CFC? And how many times did you feel that it was really a mundane job and wished there was a better way to do this? With ColdFusion 9, we have done just that! You no longer need to write those accessors. ColdFusion will automatically generate the accessor methods for you in the object. All you need to do is to define the properties using cfproperty and set the attribute ‘accessors’ to true on the component.

Consider this CFC Person.cfc

/**
 * @accessors true
 */
Component Person{
    property firstname;
    property lastname;
    property age;
    property city;
    property state;
}

When an object is created for this CFC, you can directly call the setters and getters for the properties as

<cfscript>
    person = new Person();
    person.setFirstName("Brad");
    person.setLastName("Pitt");
    person.setAge(46);
 
    writeOutput("Name : #person.getFirstName()# #person.getLastName()#");
    writeOutput("Age : #person.getAge()#"); 
</cfscript>

The implicit setter/getter uses the ‘variable’ scope, which is a private scope for a object, for storing the data. i.e the setter method puts the data in the variable scope and the getter method gets the data from the variable scope.

What if you want to override the setter/getter method? Ofcourse you can do that. You just need to define those methods in your CFC and ColdFusion will call your method instead of calling the implicit one.

Hmm.. What if you dont want ColdFusion to generate getter or setter or both methods for a particular property? You can disable that by adding attribute getter=”false” and setter=”false” on the property.

So if you define a property

property name="city" getter="false" setter="false";

ColdFusion will not generate getCity() and setCity() methods for this CFC.

The implicit methods can also do some nice validation if you have given the ‘type’ for properties. Consider the same Person.cfc with type specified where we have made age as a numeric type.

/**
 * @accessors true
 */
Component Person{
    property string firstname;
    property string lastname;
    property numeric age;
    property string city;
    property string state;
}

ColdFusion will do the datatype validation whenever the setter method is called for any property. So if you call

<cfscript>
    person = new Person();
    person.setFirstName("Brad");
    person.setLastName("Pitt");
    person.setAge("LA");
</cfscript>

It will throw a nice error saying “The value cannot be converted to a numeric”.

Whats more interesting is that you can do a whole lot of validation using cfproperty. We have added two more attributes on cfproperty named ‘validate’ and ‘validateparams’. These attributes allow you do even more advanced validations of the property data when the setter method is called for a property. (This is similar to cfparam or cfform validation).

The possible values for validate attributes are

  • string

  • boolean

  • integer

  • numeric

  • date

  • time

  • creditcard: A 13-16 digit number conforming to the mod10 algorithm.

  • email: A valid e-mail address.

  • eurodate: A date-time value. Any date part must be in the format dd/mm/yy. The format can use /, -, or . characters as delimiters.

  • regex: Matches input against pattern specified in
    validateparams

    .

  • ssn: A U.S. social security number.

  • telephone: A standard U.S. telephone number.

  • UUID: A Home Universally Unique Identifier, formatted ‘XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXX’, where ‘X’ is a hexadecimal number.

  • guid: A Universally Unique Identifier of the form “XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX” where ‘X’ is a hexadecimal number

  • zipcode: U.S., 5- or 9-digit format ZIP codes

The ‘validateparams’ attribute available with
<cfproperty>

takes the parameters required by the validator specified in the ‘validate’ attribute. This needs to be specified in the implicit struct notation.

  • min: Minimum value if ‘validate’ is integer/numeric/

  • max: Maximum value if the ‘validate’ is integer/numeric/

  • minLength: Minimum length of the string if the ‘validate’ is string

  • maxLength: Maximum length of the string if the ‘validate’ is string

  • pattern: regex expression if the validator specified in ‘validate’ attribute is regex

Consider the Person again where we will add few more properties with some validation

/**
 * @accessors true
 */
Component Person{
    property string firstname;
    property string lastname;
    property numeric age;
    property string city;
    /**
     * @validate string
     * @validateparams {minLength=2, maxLength=2}
     */
    property string state;
    /**
     * @validate zipcode
     */
    property numeric zip;
    /**
     * @validate telephone
     */
    proeprty phone; 
}

Now when you create an object of Person and call setState(state), before setting the data for state in variable scope, ColdFusion will validate that state value provided is of type ‘string’ and its length is 2. Similarly setZip() will validate that the input data is a valid zip code and setPhone() will validate that the input data is a valid telephone number.

For String type properties, you can also do regular expression validation allows you to have all sort of validation on a property of string type.

And to top it all, all of these nice goodies are available to you at a much lesser cost than regular UDFs. Yes, you read it right. Implicit methods perform much better than regular UDFs that you write in CFC. To confirm that, lets use this CFC where we will use implicit methods for ‘firstName’ and write our own accessors for ‘lastName’.

/**
 * @accessors true
 */
component 
{
    property String firstName;
    lastName = "";
 
    public void function setLastName(string name)
    {
        lastName = name;
    } 
 
    public string function getLastName()
    {
        return lastName;
    }
}

Both implicit methods and UDFs are doing exactly the same thing i.e settings and getting the data in/from variable scope. Now lets run this comparison test

<cfscript>
    person = new Person();
    t = getTickCount();
    for(i = 0; i &lt; 100000; i++)
    {
        person.setfirstName("Brad");
        fname = person.getFirstName();
    }
    writeOutput("Total Time in implicit methods " & (getTickCount() - t));
    t = getTickCount();
    for(i = 0; i &lt; 100000; i++)
    {
        person.setLastName("Pitt");
        lname = person.getLastName();
    }
    writeOutput("Total Time in UDF methods " & (getTickCount() - t));
</cfscript>

Here is the output

Total Time in implicit methods 63
Total Time in UDF methods 485

Thats almost eight times faster than regular UDF. Isn’t that sweet? You get those auto-generated methods, whole lot of auto-magical validations and to top that, incredible performance. I am sure writing accessors for your CFC fields will become a thing of past now !

Update : Post public beta, we have disabled implicit getters/setters for non-persistent CFC. To enable it, you need to set “accessors=’true’” on the component. For persistent CFC, the implicit getters/setters will always be enabled. I have changed the examples above to reflect this.