It's probably similar to what Steve Bryant does. From what I  
understand, you're looping over the query in the service layer, adding  
or transforming the query as appropriate to provide the values that in  
regular OO you'd get at by using getters on the business object. The  
query then acts as a value object (without getters and setters, but  
really it's the same thing), passing the actual results of what the  
getter calls on the bean would have been.

A few comments:
Firstly, sometimes you HAVE to create VO's - such as if you're sending  
them over the wire to a Flex app as you can't send cf code over the wire
Secondly it solves the performance problem of one bean per record  
which can be nice

However, there are some downsides.

I personally find this approach (which I tried a while back) gets  
difficult to maintain when you have a fairly large number of custom  
properties - especially when they are interdependent. In OO code my  
getTotalPrice() could call getSubTotal() and getShippingCost(). Using  
a transformation on the query, you have to be careful to make sure you  
transform the shippingcost and subtotal before you transform the  
totalprice which depends upon them. You also don't have an object in  
the view so you can't do anything nice like #Order.getItems()# or  
#User.getAddresses()#.

Personally I find the IBO solves the performance problems and I find  
the getters and setters on the business object to be easier to  
maintain as my apps get more business logic. It's also more consistent  
with what an OO programmer would expect coming from a popular OO  
language like Java or C#. So, on balance I prefer the IBO and custom  
getters for handling the transformations, but as with anything, give  
it a try both ways and see what works best for your use case.

And as for VO's, I have a method in my beans for spitting out either a  
value object or modified query so I can still use the same getter  
logic in the beans for applying the transformations.

Best Wishes,
Peter


On Jul 17, 2008, at 6:04 AM, sparkpool wrote:

>
> Any comments? Is this a strategy other folks have tried, or considered
> and rejected? How does it feel in OO terms (I'm never sure I've got a
> reasonable approach on that level)?
>
> Thanks,
>
> s
>
> On Tue, Jul 15, 2008 at 11:19 AM, sparkpool <[EMAIL PROTECTED]>  
> wrote:
>> Not sure I'm being clear here; there's no query of queries  
>> involved. A
>> query gets passed in and modified, with one or more columns of data
>> from some other planet having been added to it.
>>
>> Internally to the decorator method, an array of user names gets  
>> built,
>> corresponding to the IDs in the column of the passed query named by
>> userIDColName. That array then gets added to the passed query with
>> QueryAddColumn, using the passed userNameColName as the name for the
>> new column. Passing in the source ID column and desired userName
>> column lets you do things like call it twice to populate
>> CreatedByUserName and ModifiedByUserName columns, based on
>> CreatedByUserID and ModifiedByUserID.
>>
>> In use, it'd look semething like this:
>> --------------------
>> <cfquery name="qryWidgets" datasource="#application.dsn#">
>>       SELECT WidgetID, WidgetName, ModifedByUserID
>>         FROM Widgets
>> </cfquery>
>>
>> <cfscript>
>>       UserDAO.addUserNamesToQuery(query=qryWidgets,
>> idColumn=''ModifedByUserID', nameColumn='ModifiedByUserName');
>> </cfscript>
>> --------------------
>> That'd have the effect of adding a ModifiedByUserName column to  
>> qryWidgets.
>>
>> The source of the user names in this specific case is an LRU cache,
>> which goes to the db on a cache miss. We also have some additional
>> arguments to provide a default for empty/0, and format multiple names
>> in the case where the ID column contains a list of IDs.
>>
>> Make sense?
>>
>> s
>>
>> On Tue, Jul 15, 2008 at 4:34 AM, Alan Livie
>> <[EMAIL PROTECTED]> wrote:
>>>
>>> Thanks sparkpool / barry
>>>
>>> I'm curious too!
>>>
>>> Can you elaborate on some of the internals of your query decorator.
>>>
>>> It's good to see alternatives.
>>>
>>> Alan
>>>
>>> ________________________________________
>>> From: [email protected] [EMAIL PROTECTED] On Behalf  
>>> Of Barry Beattie [EMAIL PROTECTED]
>>> Sent: 15 July 2008 03:38
>>> To: [email protected]
>>> Subject: [CFCDEV] Re: Iterators / IBO's
>>>
>>> just curious, you're adding additional data to that query, using
>>> userIDColName as a foreign key?
>>>
>>> if so, what's happening internally? munging two queries together and
>>> having the final form of the data stored/ accessible as a
>>> Query'O'Query?
>>>
>>>
>>>
>>> On Tue, Jul 15, 2008 at 12:21 PM, sparkpool <[EMAIL PROTECTED]>  
>>> wrote:
>>>>
>>>> I'm not sure how this fits into best practices and all, but another
>>>> option I've used is "query decorator" methods, which add one or  
>>>> more
>>>> columns of related or calculated data to a passed query. An example
>>>> might be addUserNameToQuery(query, userIDColName, userNameColName).
>>>> Methods like this exist in their own domain's code, a DAO most  
>>>> likely
>>>> I'd think, allowing it to participate in processes that collect
>>>> completely "foreign" data, in an encapsulated way, without the
>>>> performance hit of instantiating a bean per composite row. This
>>>> strategy is especially helpful for items needed in many different
>>>> contexts, that are either hard to query for directly, or that you  
>>>> want
>>>> to LRU cache or otherwise pre-process.
>>>>
>>>> Not sure if I'm being clear about this, or if it's considered bad
>>>> form, but I've definitely found it a useful pattern.
>>>>
>>>> s
>>>>
>>>> On Tue, Jul 8, 2008 at 5:37 PM, Alan Livie <[EMAIL PROTECTED] 
>>>> > wrote:
>>>>>
>>>>> Thanks for this Kevan.
>>>>>
>>>>> The quick 'logic in the view' fix went live and I was given a  
>>>>> day to do a refactoring before moving onto something else.
>>>>>
>>>>> I would like a good stab at a) and your ideas are along the  
>>>>> lines I want to go down. It's still a bit vague thouh the best  
>>>>> way to do it. In the end I did something like b).
>>>>>
>>>>> I have a new 'display' bean that is composed of the main BeanA  
>>>>> but has additional properties for the other 'odds'n'ends' it  
>>>>> needs.
>>>>>
>>>>> I don't really have duplication in the getters and setters as  
>>>>> onMissingMethod() nicely takes care of most of them. I do have  
>>>>> delegate methods though in the display bean delegating to BeanA  
>>>>> making the Iterator's loadQuery() work as normal.
>>>>>
>>>>> It's not fully OO but it does keep the controllers and views  
>>>>> free of duplicated business logic and works ok for now. If in a  
>>>>> few months time we go 'doh' we can dio more refactoring into a  
>>>>> more complex a) solution with the Iterator populating several  
>>>>> beans but possibly with only the data the View actually needs  
>>>>> (it will keep the dba happy too:-)
>>>>>
>>>>> Alan
>>>>>
>>>>>
>>>>> ________________________________________
>>>>> From: [email protected] [EMAIL PROTECTED] On  
>>>>> Behalf Of Kevan Stannard [EMAIL PROTECTED]
>>>>> Sent: 08 July 2008 21:21
>>>>> To: [email protected]
>>>>> Subject: [CFCDEV] Re: Iterators / IBO's
>>>>>
>>>>> Hi Alan
>>>>>
>>>>> This is a great question.
>>>>>
>>>>> (a) sounds like a good solution. Just thinking this one through  
>>>>> - your BeanA
>>>>> would have functions like beanA.getBeanB() and beanA.getBeanC(),  
>>>>> but then
>>>>> your BeanA needs to know how to get access to BeanB and BeanC  
>>>>> all the time.
>>>>> You would also have a function like beanA.loadQuery(query,row)  
>>>>> which would
>>>>> populate beanA as well as populate the composed BeanB and BeanC  
>>>>> (they would
>>>>> perhaps also have corresponding loadQuery() functions and would  
>>>>> take the
>>>>> same query as a parameter). Not sure if you should "recreate" or
>>>>> "repopulate" BeanB and BeanC each time though - probably depends  
>>>>> on how
>>>>> complex your bean initialisation is.
>>>>>
>>>>> If your BeanA does not currently know how to get access to BeanB  
>>>>> and BeanC
>>>>> then perhaps you could create some kind of decorator/wrapper  
>>>>> around BeanA (a
>>>>> ComposedBeanA, for example) that has all of the functions of  
>>>>> BeanA but adds
>>>>> the extra getBeanB(), getBeanC() and loadQuery() functions.
>>>>>
>>>>> For (b) you would want to avoid any duplicate code in the  
>>>>> getters/setters of
>>>>> this new bean and the original beans. You might end up composing  
>>>>> the
>>>>> original bean objects inside the new one anyway so it would  
>>>>> perhaps end up
>>>>> looking like the ComposedBeanA object.
>>>>>
>>>>> Another option would be to just put the new function in its own  
>>>>> separate
>>>>> calculator/helper component and just pass in the parameters it  
>>>>> needs, then
>>>>> continue using the raw query data for the display. Not a very OO  
>>>>> solution
>>>>> but will probably take only 10 mins to implement ...
>>>>>
>>>>> Kevan
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: [email protected] [mailto:[EMAIL PROTECTED]  
>>>>> On Behalf Of
>>>>> Alan Livie
>>>>> Sent: Saturday, 5 July 2008 7:46 PM
>>>>> To: [email protected]
>>>>> Subject: [CFCDEV] Iterators / IBO's
>>>>>
>>>>>
>>>>> I'm an occasional user of iterators.
>>>>>
>>>>> I have a query that involved joins on several tables because  
>>>>> data from those
>>>>> tables is needed inside the <cfoutput query in the View. Logic  
>>>>> started
>>>>> creeping into the View as the query was looped.
>>>>>
>>>>> ie
>>>>>
>>>>> <cfoutput query="qGetXXX">
>>>>>   <cfif qGetXXX.thisBoolCol>
>>>>>      <cfset valueToDisplay = qGetXXX.aNumericCol *
>>>>> qGetXXX.anotherNumericCol>
>>>>>   <cfelse>
>>>>>        <cfset valueToDisplay = qGetXXX.aNumericCol + 1 />
>>>>>   </cfif>
>>>>> </cfoutput>
>>>>>
>>>>> I want to use the Iterator so the logic is taken out the view  
>>>>> but I get the
>>>>> performance benefit of query instead of bean array.
>>>>>
>>>>> My question is about the complexity of the bean and apologies if  
>>>>> it isn't
>>>>> the best explanation I give!
>>>>>
>>>>> The data returned in the query is from several tables but only  
>>>>> one or two
>>>>> columns may be used. I have simple beans for most of the tables  
>>>>> involved in
>>>>> the joins.
>>>>>
>>>>> Should I
>>>>>
>>>>> a) Create a complex bean with associations to the other beans ie  
>>>>> beanA has
>>>>> its own properties but is composed of a BeanB and BeanC even  
>>>>> though I only
>>>>> need one property out of BeanB and 2 from BeanC.
>>>>> b) create a new bean specific to what the page / query is doing   
>>>>> ie have a
>>>>> BeanD with properties of all the display data I need where I can  
>>>>> still use
>>>>> getters to provide the encapsulation I need.
>>>>>
>>>>> My thinking is a) is a more elegant solution and more reusable  
>>>>> but I need to
>>>>> do more work to build the bean in my bean factory and also bring  
>>>>> more data
>>>>> out of the db and b) is quicker, leaner but I have little chance  
>>>>> of reusing
>>>>> it elsewhere in the app.
>>>>>
>>>>> Any thoughts? Especially from users of Iterators / IBO's
>>>>>
>>>>> Alan
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>
>>>>
>>>>>
>>>>
>>>
>>>
>>>
>>>>>
>>>
>>
>
> >


--~--~---------~--~----~------------~-------~--~----~
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