You could just have a base class that is initialized in the contructor
with a reference to this "kernel" object/reference, and has a private
method called "getKernel()" or just "kernel()" that returns a
reference to that variable.  You could then have all of your classes
inherit from this base class and have them access the kernel via the
"getKernel()" or "kernel()" method.

The downside to this is that all your derived objects would have to be
require the kernel rererence in their own constructors.

Another solution would be to create a method on the base class called
"setKernel()" that could be called after the class constructor, but as
part of the initialization of the object.  This could be done inline
by the calling code, or it could be done inside a factory (class or
method--I prefer factory classes myself).

For this to work, you would create a class called something like
"Factory" with a constructor method that requires a reference to the
kernel.  It then saves this to a private instance variable like
"variables.kernelRef".  For each type of object that your application
needs, have a method called "get<TypeName>()" that is responsible for
creating that object and setting the kernel reference by calling
"setKernel(variables.kernelRef)".   As an aside, if your factory class
is in the same directory as the classes it instatiates, you could set
the access attribute of the "setKernel()" method to "package" to lock
it down more.  If you want, the factory method could also call the
constructor for the new object.

Here is some code:

<cfcomponent name="Factory" hint="This is your factory class.  It is
responsible for creating other objects.">

        <cfset variables.kernelRef = "">

        <cffunction name="init" returntype="Factory" access="public">
                <cfargument name="kernel" type="struct" required="true"/>
                <cfset variables.kernelRef = arguments.kernel>
                <cfreturn this/>
        </cffunction>
        
        <cffunction name="newPerson" returntype="Person" access="public">
                <cfset var person = CreateObject("component", "Person").init()>
                <cfset person.setKernel(variables.kernel)>
                <cfreturn person/>
        </cffunction>   

</cfcomponent>

<cfcomponent name="Object" hint="This is your base class">
        <cfset variables.kernelRef = "">

        <cffunction name="init" returntype="Object" access="public">
                <cfreturn this/>
        </cffunction>
        
        <cffunction name="setKernel" returntype="void" access="package">
                <cfargument name="kernel" type="struct" required="true"/>
                <cfset variables.kernelRef = arguments.kernel>
        </cffunction>
        
        <cffunction name="kernel" returntype="struct" access="private">
                <cfreturn variables.kernelRef/>
        </cffunction>
        
</cfcomponent>

<cfcomponent name="Person" extends="Object">

        <cffunction name="init" returntype="ApplicationClass" access="public">
                <cfreturn this/>
        </cffunction>
        
        <cffunction name="callMe" returntype="void" access="public">
                <!--- Does nothing --->
        </cffunction>

</cfcomponent>
On Tue, 13 Jul 2004 01:55:10 -0500, Barry L Beattie <[EMAIL PROTECTED]> wrote:
> ahhhh...
> well, I'm sort of there. I realise that there should not be ANY reference to session 
> or Application scope within the CFC because those shared scopes can get changed from 
> external influences.
> 
> to be honest, I thought request and server were, perhaps, excusable. obviously not.
> 
> we're trying to introduce a "kernel" idea as a central point for getDSN(), error 
> reporting, setup settings and in this case utils. stored in server scope, the app 
> MUST NOT run without this singleton object existing.
> 
> the kernel is created only in one spot and any changes have to go thru only one 
> path.  Every other CFC can rely on this kernel for what it needs on a global level. 
> we use the Application.cfm to copy it over to request scope as a snapshot of the 
> data at that point (any changes to the kernel will be picked up on the next request)
> 
> is it really that bad to bend encapsulation this way? or is there a better way to 
> use this kernel CFC?
> 
> 
> >>>> <cfreturn request.kernel.utils.arrayostructs(qry) />
> 
> >>That's a violation of encapsulation, plain and simple.
> >>Something Barney and I wouldn't do
> 
> understood because at that point the CFC is referencing an external scope. But how 
> would be the best way to use such a util function? Instanciate it in the INIT() of 
> every CFC wanting it?
> 
> thanx
> barry.b
> 
> 
> > Forgive me Sean but I can't see the problem.
> 
> It's one of those things that really can't be explained if you don't
> 'get' it... encapsulation is a good thing... it helps you build more
> reusable code. Referencing external stuff (like request scope or
> server scope) from inside an object is a violation of encapsulation.
> That's just a fact. Whether or not that violation of encapsulation is
> important to you depends on how much you value encapsulation. If you
> don't 'get' encapsulation then you won't value it so it's kinda
> moot...
> 
> 
> > <cfreturn request.kernel.utils.arrayostructs(qry) />
> 
> That's a violation of encapsulation, plain and simple. Something
> Barney and I wouldn't do because we value the benefits of
> encapsulation but something that others would do if they don't yet
> view encapsulation as important.
> 
> > but isn't instanciation of objects a performance hit?
> 
> Depends. And even if it is, the performance hit may well be irrelevant
> compared to the benefits of maintaining encapsulation. It's that old
> saw about never optimize unless you know you have a problem and you've
> tracked it down to something specific...
> 
> 
> 
> --
> _______________________________________________
> Talk More, Pay Less with Net2Phone Direct(R), up to 1500 minutes free!
> http://www.net2phone.com/cgi-bin/link.cgi?143
> 
> ----------------------------------------------------------
> You are subscribed to cfcdev. To unsubscribe, send an email
> to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
> in the message of the email.
> 
> CFCDev is run by CFCZone (www.cfczone.org) and supported
> by Mindtool, Corporation (www.mindtool.com).
> 
> An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]
> 


-- 
Paul Kenney
[EMAIL PROTECTED]
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]

Reply via email to