5 Replies Latest reply: Jun 7, 2009 6:47 AM by PaulKD RSS

    CFC - to init or not to init

    PaulKD Community Member

      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.

       

        • 1. Re: CFC - to init or not to init
          craigkaminsky Community Member

          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.

          • 2. Re: CFC - to init or not to init
            PaulKD Community Member

            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.

            • 3. Re: CFC - to init or not to init
              craigkaminsky Community Member

              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.

              • 4. Re: CFC - to init or not to init
                BKBK CommunityMVP

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

                • 5. Re: CFC - to init or not to init
                  PaulKD Community Member

                  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.