PS ... On the way to the post office to check my mail, i realized i forgot
to say something in my reply. :-)
Your approach of creating all your objects in Application.cfm and placing
them in application scope kind of encapsulates your object creation for now.
But this approach will break down the moment you need an object in a
different scope, say session scope.
And the way it seems you are doing it is not as efficient as it could be.
I'm looking at your example and assuming it's verbatim:
<cfset application.objectOne = CreateObject('component', 'cfc.navigation')>
<cfset application.objectTwo = CreateObject('component', 'cfc.users')>
<cfset application.objectThree = CreateObject('component', 'cfc.email')>
In this way, you recreate the objects for each request. There's little point
in using application scope in this case.
It would be much more efficient if you created a singleton factory in
application.cfm like so (with a double lock as shown, to make sure you have
only one instance of the Factory in application scope):
<cfif NOT StructKeyExists(application,"Factory")>
<cflock name="factoryLock" Timeout="10" THROWONTIMEOUT="No"
Type="Exclusive">
<cfif NOT StructKeyExists(application,"Factory")>
<cfset application.Factory = CreateObject('component','
cfc.Factory').init(passInAppSettingsHere)>
</cfif>
</cflock>
</cfif>
And then in Factory.init(), you can instantiate any singletons you need into
the variables scope of the factory and they'll persist then effectively in
application scope for the duration of your application.
A singleton, if you don't know the term, is one and only one instance of an
object that persists in application scope in CF. I guess you could also use
the term for a server scoped object.
--- simple Factory.cfc example ---
<cffunction name="init" access="public" returntype="Factory" output="no">
<cfargument name="AppSettings" type="any" required="Yes"/>
<cfset variables.AppSettings = arguments.AppSettings />
<cfset variables.Navigation = createNavigation() />
<cfset variables.Navigation.init(variables.AppSettings.getDsn()) />
<cfreturn this />
</cffunction>
<cffunction name="createNavigation" access="public" returntype="any"
output="no">
<cfset var Navigation = createObject('component','cfc.Navigation') />
<cfreturn Navigation />
</cffunction>
<cffunction name="getNavigation" access="public" returntype="any"
output="no">
<cfreturn variables.Navigation />
</cffunction>
.......
When you need your persisted Navigation object somewhere in your
application, you can do this:
application.Factory.getNavigation
().getBreadcrumb(uniqueIdentifierForThisPage)
And if you need the navigation for a particular visitor you, could do
something like this:
session.navigation = application.Factory.createNavigation()
......
session.navigation.setUserRole(session.User.getRole())
session.navigation.getUserNav()
The example might be a bit contrived, but i'm only trying to show that with
a factory, you can cache objects in application scope within the factory
itself, which means you only need to deal with double locking in one place
for singletons. Or you can use the same factory to create objects for one
time use or session scoped objects.
Different people will design factories in different ways, and use different
naming conventions for the functions. The more sophisticated your factory,
the more flexible and abstract. You could for instance build a load()
function something like this:
<cffunction name="load" access="public" returntype="any" output="false">
<cfargument name="objectName" required="Yes" type="string" />
<cfargument name="isSingleton" default="false" type="boolean" />
<cfif arguments.isSingleton IS true>
<cfif StructKeyExists(variables,arguments.objectName)>
return variables[arguments.objectName]
<cfelse>
create arguments.objectName
put it in variables scope
return variables[arguments.objectName]
</cfif>
<cfelse>
create arguments.objectName
return it
</cfif>
</cffunction>
That's fine, but what if you need to pass in parameters to your init()
function? how would you do that? What if one of your parameters is another
object?
Now we're getting close to ColdSpring, so we might as well use it. But for
most people starting out with factories, it's probably easier to get a feel
for them using a simple factory you build yourself that has separate
create() or get() functions for each object. Once the usefulness of it
really clicks, then ColdSpring might be the next step.
But i can guarantee to you that factories can be very useful. You just need
to take a few more steps into deeper water with your CFC use and it will
become apparent.
On 12/12/06, Nando <[EMAIL PROTECTED]> wrote:
>
> As others are indicating, factories become more and more useful as your
> application becomes more and more "complex".
>
> In the first app i built using CFC's, after about a year of iterations and
> improvements, i had well over 1800 CreateObject() calls in the thing. One
> day a problem arose because of the mapping to those objects. I wanted to
> fork the development, maintain the current version and keep going with a new
> one. So the 2 versions couldn't use the same mapping.
>
> I was nervous about doing a search and replace through the whole
> application, because i wasn't sure if it would break anything. So i
> carefully stepped through each CreateObject() call. It took me a long time,
> and i made a few mistakes along the way. All in all, i think it took me the
> better part of a day more or less to deal with it, after dithering about my
> approach, working through all those CreateObject() calls, and fixing my
> mistakes.
>
> It was on that day that the usefulness of factories really came home to
> me. If i had encapsulated all my CreateObject() calls in a factory, i could
> have simply copied the original, ran a quick search and replace on the copy,
> and even could have swapped the new factory in for the old one.
>
> If i had to possible fix a mapping issue every time i installed an
> instance of my app, if it were an ASP type of thing, then i'd only need to
> adjust the factory.
>
> Which makes all the instances of my app MUCH more maintainable, because i
> can roll out bug fixes to all the instances without fiddling with each one.
>
> Mike's comment about how CFC use has increased also applied to me. It
> didn't make sense to use a factory to me at first either. But the need crept
> up on me. That's the reason i'd suggest to someone for getting into
> factories early. Encapsulating object creation make your app much more
> flexible and easy to maintain, down the road. It's really true, even in
> ColdFusion.
>
> Nando
>
>
> On 12/12/06, Mike Kear <[EMAIL PROTECTED]> wrote:
> >
> > My experience has been thinking i only have a few objects so it's not
> > really worth the effort of building a factory. But i built one anyway
> > for the experience. But when i look at that first OOP project now, a
> > year later, i see my site which was originally going to have only 10
> > objects now has more than 50. I'm REALLY glad i built the factory now!
> >
> > Once you see how great this OOP thing is, you start bolting on
> > applications like there's no tomorrow, and complexity starts coming
> > looking for you.
> >
> > When you think you are only going to have a few objects, I reckon for
> > most cases, that's only because you have missed something. And you're
> > going to get more complexity anyway.
> >
> > Cheers
> > Mike Kear
> > Windsor, NSW, Australia
> > Adobe Certified Advanced ColdFusion Developer
> > AFP Webworks
> > http://afpwebworks.com
> > ColdFusion, PHP, ASP, ASP.NET hosting from AUD$15/month
> >
> >
> > On 12/12/06, Judith Dinowitz <[EMAIL PROTECTED]> wrote:
> > > >> I'm going to look for some decent example of a objectFactory and do
> > > >> some testing to see if there is a performance hit.
> > > >
> > > >That sounds like a great idea. Here is an objectFactory to look at
> > and
> > > >compare with:
> > > >http://www.phillnacelli.net/blog/index.cfm/2006/11/21/ObjectFactory-Explained
> > > >
> > > >Please let us know what you find.
> > > >
> > > >-Aaron
> > > Well, as I believe Chris Scott explained in his article "ColdSpring
> > Fundamentals" (FAQU 2), object factories really make a difference when your
> > application gets highly complex and you start having many more objects to
> > initialize with dependencies... That's what ColdSpring tries to do, to
> > manage the objects for you. If you've only got 8 or 9 objects, then maybe an
> > object factory is not for you.
> > >
> > > Judith
> > >
> > >
> >
> >
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Create robust enterprise, web RIAs.
Upgrade & integrate Adobe Coldfusion MX7 with Flex 2
http://ad.doubleclick.net/clk;56760587;14748456;a?http://www.adobe.com/products/coldfusion/flex2/?sdid=LVNU
Archive:
http://www.houseoffusion.com/groups/CF-Talk/message.cfm/messageid:263703
Subscription: http://www.houseoffusion.com/groups/CF-Talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4