Skip navigation
PaulKD
Currently Being Moderated

CFC - to init or not to init

May 17, 2009 6:17 AM

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.

 

2.

 

 
Replies
  • Currently Being Moderated
    May 17, 2009 7:19 AM   in reply to PaulKD

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    May 17, 2009 8:24 AM   in reply to PaulKD

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    May 17, 2009 9:02 AM   in reply to PaulKD

    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()>

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points