• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

CFC - to init or not to init

New Here ,
May 17, 2009 May 17, 2009

Copy link to clipboard

Copied

I have long used custom tags, but now find myself creating components. I am not an OOP developer. I have read various "best practice" articles and am still looking for a compelling reason to add an init constructor to my CFCs. I attach two very simple code examples (test.cfc), the first shows how I currently use CFCs and the second, if I understand correctly, is how I should be coding.

1.

<cfcomponent>

<cfset this.Price = 10 />

<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn this.Price />
</cffunction>

</cfcomponent>

2.

<cfcomponent>

<cffunction name="init" access="public" returntype="Test">
     <cfset variables.Price = 10 />
     <cfreturn this />
</cffunction>

<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn variables.Price />
</cffunction>

</cfcomponent>

TOPICS
Advanced techniques

Views

6.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
May 17, 2009 May 17, 2009

Copy link to clipboard

Copied

Paul,

Wanted to let you know that your attachments/code samples did not post with the topic.

There are a few reasons that it's advisable to create an init method for your CFCs. A big reason, perhaps the most significant one, in favor of using init() is to initialize constants and other variables for your CFC as well as to return an instance of the CFC to the calling page.

Another reason is that, when you don't use it, ColdFusion will invoke init() once you call a non-static method of the CFC. In short, CF will call init() to initialize it, anyway (there could be a minor performance gain for using init() when you setup the object rather than waiting for CF to do it).

Yet another reason for init() is that, if you want to have persistent access to the CFC, by storing it in the session scope for example, you must use init() because it returns a reference to an instance of the object where other approaches (cfobject, etc.) do not.

One interesting note about CFCs is that you don't need to explicitly call init() when you create an object from your CFC. You may also add an init() call to the constructor area of a CFC (typically this code is placed between the opening cfcomponent tag and the first cffunction tag) and that will get called when you instantiate the CFC:

<cfcomponent>

     <cfset init() />

     <cffunction name="init">... code ... </cffunction>

</cfcomponent>

Another interesting thing about CFCs is that the init 'method' is not really a method; rather, it's an identifier, related to how ColdFusion and Java interact. When you use (create) Java classes in your CFML, you need to use init() to call the constructor of the Java class. This isn't really relevant for a lot of us but it explains why it's called init() and not something else.

For me, most applications I build need both to initialize an object with special values (unique ids, etc.) and to persist several objects/CFCs across the application. As such, I find that staying in the habit of using init() works well for me.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
May 17, 2009 May 17, 2009

Copy link to clipboard

Copied

Long time since I used these forums - used to have insert code option, now everyting is RIA

<cfcomponent>

<cffunction name="init" access="public" returntype="Test">
     <cfset variables.Price = 10 />
     <cfreturn this />
</cffunction>

<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn variables.Price />
</cffunction>

</cfcomponent>

<cfcomponent>

<cfset this.Price = 10 />

<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn this.Price />
</cffunction>

</cfcomponent>

Also used to have a preview.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
May 17, 2009 May 17, 2009

Copy link to clipboard

Copied

I'm still getting used to the new forum text editor, too !

A key difference between the two code options you provided is that first treats the property as a private variable (good encapsulation) while the second exposes the property as a pubic variable. The former, in OOP parlance, is consider the appropriate way to do it, unless you have a very good reason to make a property public. So, option 1 is simply ColdFusion's way to adhere to these OO 'best' practices.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 17, 2009 May 17, 2009

Copy link to clipboard

Copied

Indeed, best practice is to keep the instance variable private. Here are two common ways to do it:

Test1.cfc
========

<cfcomponent>
<cfset variables.price = "">

<cffunction name="init" access="public" returntype="Test1">
<cfargument name="price" required="true" type="Numeric">
      <cfset variables.price = arguments.price>
      <cfreturn this>
</cffunction>


<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn variables.price>
</cffunction>

</cfcomponent>


myCallingPage1.cfm
=================

<cfset myObjectInstance1 = createobject("component", "Test1").init(10)>
<cfset myInstancePrice1 = myObjectInstance1.getPrice()>

------------------------------------------------------------------

Test2.cfc
========

<cfcomponent>
<cfset variables.price = "">

<cffunction name="init" access="public" returntype="Test2">
      <cfreturn this>
</cffunction>

<cffunction name="setPrice" output="no" returntype="void">
      <cfargument name="price" required="true" type="Numeric">
      <cfset variables.price = arguments.price>
</cffunction>

<cffunction name="getPrice" output="no" returntype="numeric">
     <cfreturn variables.price>
</cffunction>

</cfcomponent>


myCallingPage2.cfm
=================

<cfset myObjectInstance2 = createobject("component", "Test2").init()>
<cfset myObjectInstance2.setPrice(15)>
<cfset myInstancePrice = myObjectInstance2.getPrice()>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 07, 2009 Jun 07, 2009

Copy link to clipboard

Copied

LATEST

Thanks for the answers. In the end I've decided NOT to include an init and simply declare this variables at the top of the components, so that i can easily change their properties, if required, after instantiation e.g. instancename.DevDSN instancename.TestDSV.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation