Implicit accessors

With the evolution of ColdFusion 9 we are able to write the same powerful, functional components, but with less code. In some instances, this may be due to the fact that we no longer need to write our core components in tag format, but also due to the powerful ability to have the accessor/getter and mutator/setter methods generated for you if required.

This is achieved from the accessors attribute within the main component tag. Following is a ColdFusion 9 specific version of our complete Person component:

<cfcomponent displayname="Person" output="false" hint="I am the Person Class." accessors="true">
accessors attributeaccessors attributeabout<cfproperty name="firstName" type="string" default="" setter="false" />
<cfproperty name="lastName" type="string" default="" setter="false" />
<cfproperty name="gender" type="string" default="" setter="false" />
<cfproperty name="dateofbirth" type="string" default="" setter="false" />
<cfproperty name="hairColor" type="string" default="" setter="false" />
<cffunction name="init" access="public" output="false" returntype="any" hint="I am the constructor method for the Person Class.">
<cfargument name="firstName" required="true" type="String" default="" hint="I am the first name." />
<cfargument name="lastName" required="true" type="String" default="" hint="I am the last name." />
<cfargument name="gender" required="true" type="String" default="" hint="I am the gender." />
<cfargument name="dateofbirth" required="true" type="String" default="" hint="I am the date of birth." />
<cfargument name="hairColor" required="true" type="String" default="" hint="I am the hair color." />
<!--- Set the initial values of the Bean --->
<cfscript>
variables.firstName = arguments.firstName;
variables.lastName = arguments.lastName;
variables.gender = arguments.gender;
variables.dateofbirth = arguments.dateofbirth;
variables.hairColor = arguments.hairColor;
</cfscript>
<cfreturn this />
</cffunction>
<!--- public methods --->
<cffunction name="getFullName" access="public" output="false" hint="I return the full name of the person.">
<cfset var strFullName = '' />
<!---Concatenate the string values to return the full name. Here, we call the variables values directly. You could also call the get methods, like so: getFirstName() & ' ' & getLastName()--->
<cfset strFullName = variables.firstName & ' ' & variables.lastName />
<cfreturn strFullName />
</cffunction>
<cffunction name="getAgeInYears" access="public" output="false" hint="I work out the age of the person in years based upon the current date.">
<cfset var strAgeInYears = '' />
<cfset strAgeInYears = dateDiff('yyyy', getDateOfBirth(), now()) />
<cfreturn strAgeInYears />
</cffunction>
<cffunction name="getMemento" access="public" output="false" hint="I return the variables scope.">
<cfreturn variables />
</cffunction>
</cfcomponent>

Listing 3.16 - Using Implicit Accessors in Person.cfc

The first thing you may notice is the length of the component content in comparison to our previous version in Listing 3.15, which is now much shorter. You will also notice that there are no mutator/setter methods and no accessor/getter methods that deal with the property values directly. We do have our 'custom' methods as well as the init() constructor, but no other methods.

This is due to the accessors attribute, set at the top of the document. By including this attribute and setting the value to true, the getters and setters are generated for you.

By generating all methods this way, they are all set to public access, meaning that all setter methods would be available to access outside of the component; perfect for a read/write component, as we have already seen.

In our previous component in Listing 3.15, we created a read-only component, and opted to set all of our property values within the constructor method. This effectively removed the need for any setter methods at all, although we kept them in.

In Listing 3.16, both the getter and setter methods are generated automatically. To convert this component into a read-only object and remove the setter methods completely, we can restrict the setter methods from being created as per our example by setting the setter="false" attribute within each cfproperty tag. This tells ColdFusion not to generate any setters for these properties.

Following this, our Person.cfc UML diagram would now look as follows:

Implicit accessors

When using the automatically-generated methods, the property values are stored and retrieved from the variables scope itself, whereas in our hand-written example, we were storing the values within variables.instance. To reflect this change, the code in Listing 3.16 was amended to reference only the variables scope, and not the variables.instance structure.

Listing 3.17 - shows the same Person ColdFusion component using the implicit getters, written in pure script syntax.

component displayname="Person" hint="I am the Person Class." accessors="true"
{
property name="firstName" type="string" default="" setter="false";
property name="lastName" type="string" default="" setter="false";
property name="gender" type="string" default="" setter="false";
property name="dateofbirth" type="string" default="" setter="false";
property name="hairColor" type="string" default="" setter="false";
public any function init(
required string firstName = "", required string lastName = "", required string gender = "", required string dateofbirth = "", required string hairColor = "") output = "false" hint="I am the constructor method for the Person Class."
{
/*
Store the values into the variables scope.
We do not have mutator/setter methods
within this component, but we can set the
values into the variables scope directly.
*/
variables.firstName = arguments.firstName;
variables.lastName = arguments.lastName;
variables.gender = arguments.gender;
variables.dateofbirth = arguments.dateofbirth;
variables.hairColor = arguments.hairColor;
return (this);
}
public string function getFullName()
output="false" hint="I return the full name of the person."
{
local.strFullName = variables.firstName & ' ' & variables.lastName;
return local.strFullName;
}
public string function getAgeInYears() output="false" hint="I work out the age of the person in years based upon the current date."
{
local.strAgeInYears = dateDiff('yyyy', getDateOfBirth(), now());
return local.strAgeInYears;
}
public any function getMemento()
output="false" hint="I return the variables scope."
{
return variables;
}
}

Listing 3.17 - Person.cfc written in script syntax (ColdFusion 9 only)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.103.210