Nathan,
        As someone trying to move up the OOP/CFC as rapidly as possible, I
find your posts to be clear, practicable and to have just enough theory to
make your point.  For example, I've been wrestling with how to handle both
global and application specific environmental variables for a portal I am
rebuilding (for the 3rd time).  Your post below just made the light go on!!

Please keep posting!  And please share your code.

Walt

Walt Sparrow-Hood
Director, E-Commerce
GenTek, Inc.
[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> 



-----Original Message-----
From:   Nathan Dintenfass [SMTP:[EMAIL PROTECTED]
Sent:   Tuesday, August 19, 2003 11:52 PM
To:     [EMAIL PROTECTED]
Subject:        RE: [CFCDev] Suggestions for Handling Multi-Use Methods

Well, I figured people might be getting sick of my constant posts to this
list, but since nobody else is answering..... ;)

Here's one way to consider doing what you're talking about:

You could use what the patterns people call "composition" to have your
components use each other.  It's a fancy word for basically just having
components use other components functionality.  So, you might do something
like this:

application.ActiveDirectoryService =
createObject("component","ActiveDirectoryService").init();

application.UserService =
createObject("component","UserService").init(application.ActiveDirectoryServ
ice);

In that scenario you would be passing UserService an instance of the
ActiveDirectoryService when you instantiate -- you then have two cached
component instances, one of which (UserService) has an internal "instance"
reference to the ActiveDirectoryService.  The guts of the UserService can
then use the ActiveDirectoryService in its instance data without worrying
about where that instance actually lives (which in that case of that code
would be in the Application scope).

So, now UserService has a clean way to use ActiveDirectoryService.

When you instantiate your AceLinkUser into the session you could then pass
the UserService to your init() method of AceLinkUser.  UserService could
then expose whatever methods are needed in ActiveDirectoryService.  Or, you
could just pass both to the UserService.  Since components pass by reference
there should be very little overhead associated this doing it that way.  You
might also consider having the init() method of AceLinkUser just get
whatever information is needed from the other services directly.  That is,
rather than having the AceLinkUser component actually call those methods,
just call them when you instantiate.  In other words, instead of this:

session.AceLinkUser =
createObject("component","AceLinkUser").init(username,application.UserServic
e);

You could just do:

session.AceLinkUser =
createObject("component","AceLinkUser").init(username,application.UserServic
e.isFacutly(username));

Which one you use will depend on the extent to which the AceLinkUser uses
the methods of the UserService and ActiveDirectoryService during its life a
lot or just during instantiation.

I'm also not sure if it's necessarily bad if both the UserService and the
AceLinkUser have an isFaculty method.  The UserService's isFaculty method
receives a username and does some kind of data retrieval to give you the
answer.  The AceLinkUser's isFaculty() method just returns a boolean value
(presumably already stored in the instance data) without needing an
argument.  So, although the methods have the same name, they serve different
and appropriate purposes in the respective components.

Those with greater OO design experience may have a better critique, but I've
had good success using composition -- particularly when I build a single
component that gives the developer an API to use, where that single
component has a few other "services" that get passed at init() time.  That
way the developer needs to learn only a single component's API and I can
worry about the ways they interact with each other.  Thus, I achieve a clean
separation of interface from implementation.  If you're interested in a
working example, I'm almost ready to do the first public alpha test of a
blogging tool that makes extensive use of composition
(impart.sourceforge.net).  I'd be happy to share that code, rough as it may
be in its current form.

 - Nathan



> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> Behalf Of Dawson, Michael
> Sent: Tuesday, August 19, 2003 12:08 PM
> To: [EMAIL PROTECTED]
> Subject: [CFCDev] Suggestions for Handling Multi-Use Methods
>
>
> I'm struggling with the best location to put some methods that will be
> used for both loading a session-based instance as well as performing
> simple actions.
>
> For example, I have three components:
>
> AceLinkUser
> --The main component
> --Is aware of the user; stores data in an instance variable
> --An instance of this will be stored in the session scope
> --Calls methods from ActiveDirectoryService to load data during Init()
> --Calls methods from UserService to load data during Init()
>
> UserService
> --Used to gather user-related information
> --Is unaware of data; only returns data to the caller; no instance
> variables
> --Calls methods from ActiveDirectoryService
> --Contains methods that pull information from other data sources
>
> ActiveDirectoryService
> --Communicates with Active Directory
> --Is unaware of data; stores connection information in an instance
> variable
> --Does not consume any other components
> --Contains the main LDAP query method
> --Contains other utility methods that use the LDAP query method
>
> As you can see, AceLink user calls the other two components.
> UserService, in turn, may also call the ActiveDirectoryService
> component.
>
> To instantiate my AceLinkUser object, I need to know if a user is a
> faculty member.  This information is stored in an Active Directory
> domain group.
>
> Currently, AceLinkUser's Init() calls "IsFaculty(username) method from
> the UserService component.  I could have also placed this same method in
> the ActiveDirectoryService component, but I felt it would be best to
> "abstract" the call by creating a UserService component.
>
> Is it best to keep the methods "at the lowest level" in the component
> organization?  Where is the best location for IsFaculty()?
>
> Is it bad to have a single component call a common component directly AS
> WELL AS call a compoent that, in turn, calls the common component?
>
> I'm not really concerned about performance at this time.  I'm only
> interested in how components would be best structured in this example.
>
> Thanks
>
> M!chael A. Dawson
> Group Manager, Programming and Software Development
> Office of Technology Services
> University of Evansville
> 1800 Lincoln Avenue
> Evansville, IN 47722
> 812-479-2581

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

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the word 'unsubscribe cfcdev' 
in the message of the email.

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

Reply via email to