On Feb 1, 2008 8:28 AM, Brian Sadler <[EMAIL PROTECTED]> wrote:
> I think if you're going couple the DAO to anything then the bean is
> the obvious choice, given that the DAO receives the bean as an
> argument and you have to access the beans properties or getters &
> setters within most of the DAOs CRUD methods.  It seems natural to me
> anyway! :-)

You're talking about a specific implementation so in some ways your
argument is circular. Because of the way you implement things, your
approach makes more sense :)

> Also if you look at the DAO entry in the j2ee pattern catalog (http://
> java.sun.com/blueprints/corej2eepatterns/Patterns/
> DataAccessObject.html) the bean creates the DAO (my token appeal to ha
> higher authority)!

I think you misread the pattern. The DAO is a service and is pretty
much interchangeable with the Table Data Gateway in Fowler. Fowler
even comments on the similarity. Did you mean "the DAO creates the
bean"?

I guess I was responsible for CFers separating persistence code into
DAOs (per-object) and Gateways (aggregate) and that was meant to be a
helpful rule of thumb to get OO n00bs to think about objects separate
from regular ol' queries. That was something I probably should have
corrected within a year or two but now, nearly five years later, my
Mach II Development Guidelines are still referred to for that
"pattern" - even tho' the doc hasn't been updated for years (I moved
on from the Web Technology Group and did several years on other teams
and finally left Adobe a year ago).

Here's what I do:

First off, I have data gateway objects. They usually manage
persistence for a group of tightly related tables, rather than just
one table. They handle single object persistence and aggregate data
operations. They are, essentially, what the J2EE DAO / Fowler TDG
patterns represent except that they are not religiously 1:1 with the
underlying tables.

Second, I use Transfer for all my actual persistence. I implement my
data gateways in terms of Transfer (so Transfer is (almost) completely
encapsulated).

Third, I use decorators for all my Transfer objects and they all have
a save() method that simply calls getTransfer().save(this); In fact
I'm starting to use a BaseDecorator CFC now that includes that method
and just have my regular decorators extend it so I only write the
method once. I tend not to have cascading saves, preferring to update
objects atomically where possible (if I had to deal with it, I'd be
more inclined to cascade in the service which is where transactions
belong, not in the beans themselves). Note also that if I need a
transactional operation, the service needs to ask Transfer to clone
the objects and then work with the clones and then saving them all
consistently in a transaction. That is *not* something a single
business object should know about!

Fourth, I use Brian Kotek's incredibly awesome TDO Bean Injector
Observer (which I hope will soon become part of the core ColdSpring
code) to inject any services needed by the beans automatically. Now,
all my business objects (Transfer-managed beans) have access to any
services that they need without needing to know about how the rest of
the system works.

Fifth, I'm starting to use a BaseGateway CFC that uses
onMissingMethod() to implement a number of common persistence methods
such as get{Object}ById(id) and findAll{Object}s() and so on. Specific
gateways extend this. In ColdSpring, I define the BaseGateway as an
abstract bean and specify the constructor-arg values for transfer and
datasource beans (which ColdSpring gets from transferFactory via the
factory-bean / factory-method constructs). I define individual
gateways to have baseGateway as a parent bean and specify a
constructor-arg that specifies the package name for that gateway (all
my Transfer objects live in packages so each gateway typically
operates on only one package).

Here's an example of my ColdSpring XML for that:

        <!-- main Transfer factory object -->
        <bean id="transferFactory" class="transfer.TransferFactory">
                <constructor-arg name="configuration"><ref
bean="transferConfiguration" /></constructor-arg>
        </bean>
        
        <!-- convenience objects for injection, instead of using the Transfer
factory -->
        <bean id="transfer" factory-bean="transferFactory"
factory-method="getTransfer" />
        <bean id="datasource" factory-bean="transferFactory"
factory-method="getDatasource" />
        
        <!-- autowiring bean injector -->
        <bean id="transferBeanInjector"
class="coldspring.transfer.TDOBeanInjectorObserver" lazy-init="false">
                <constructor-arg name="transfer"><ref 
bean="transfer"></ref></constructor-arg>
                <constructor-arg 
name="suffixList"><value>service</value></constructor-arg>
                <!-- use debug mode in development -->
                <constructor-arg 
name="debugMode"><value>true</value></constructor-arg>
        </bean>
        
        <!--
                Data layer object definitions
        -->
        <bean id="baseGateway" class="project.model.data.BaseGateway" 
abstract="true">
                <constructor-arg name="transfer"><ref 
bean="transfer"/></constructor-arg>
                <constructor-arg name="datasource"><ref 
bean="datasource"/></constructor-arg>
        </bean>
        
        <bean id="assetGateway" class="project.model.data.AssetGateway"
parent="baseGateway">
                <constructor-arg 
name="packageName"><value>asset</value></constructor-arg>
        </bean>

If I say assetGateway.getVendorById(42), the base gateway's
onMissingMethod() is called and ultimately returns
transfer.get("asset.vendor",42) - I don't have to write any of the
common persistence operations so CRUD is automatic - no code needed
anywhere (outside the base decorator and base gateway - my base
gateway implements getNew{Object} and delete{Object} as well as
get{Object}ById).
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CFCDev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cfcdev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to