By Peter Bell

Introducing "the CFArgument" with Brian Rinaldi

While we're still waiting for UFC style cage fighting in the ColdFusion world (hopefully at cf.Objective() next year :-) ) Brian Rinaldi and I decided to cook up a new series of postings.

CF Argument is all about taking two sides of an argument and seeing where it leads. The first installment covers the iterating business object. Hopefully we'll be able to make this a weekly thing . . .

Rebuilding my Base Object

As you might have guessed from my last few postings, I'm doing a ground up "clean up" of all of my LightBase code. The starting point is to give my base object a quick going over . . .


Storing Instance Data in Beans vs. IBOs

As part of my generic getters and setters I like to put my instance data for all of my beans into a struct so there is no chance that instance data and methods will overwrite each other (which might otherwise be a possibility if both ever had the same names). But when I start to play with IBO's, I have two types of data to store - instance/object data and class data . . .


IBO Sample Code

I created a project for the Iterating Business Object some time back but never got a chance to upload code as my iterating business object is firmly embedded into my in-house framework so it doesn't really exist as its own bean.

After some pressure I finally uploaded a ZIP file to the project. It is just a single cfc with all of the key methods and I haven't had a chance to test it on its own, but it should give a pretty good idea of my implementation for anyone who wants to do something like this.

Two design decisions that are most arguable (IMO):

  • There is a question as to whether a business object should really know how to iterate itself - it might make more sense to have a separate iterator or at least to compose the iterator. While true in practice, when you try to implement this (without actually creating an array of beans) the implementation gets a little messy. I think a cogent argument could be made for decorating business objects with an iterator instead of having base business object methods for iteration, but this is working for me, so I'm not in a rush to change it purely for architectural purity (although I may play with that fairly soon).
  • The next() iterator method is both a command and a query, incrementing iterator and returning a boolean with a 0 if there isn't a next record. I think there is something to command query separation, but this simplifies my iterator interface allowing for the code snippet below to work, so I'm happy with the hack.

<cfset ObjectList.reset()>
<cfloop condition="">
#ObjectList.get("Title")#<br />

Of course, you could argue with the whole generic getter/setter approach as making the API of the bean less explicit, but for my use case there's no way I'm going to generate a bunch of dumb getters and setters to bulk up a code base that human beings really aren't supposed to be looking at most of the time anyway.

Then there is the question of why bother with this at all rather than just a collection of actual business objects. Answer is instantiation costs for displaying lists and by having a performant approach to instantiation what appears to be a collection of business objects it means I can ALWAYS use the same approach rather than having to start with queries and then refactor my views and other code as I find a business object has more calculated properties than I realized.


Retrieving Beans with Rich Getters in Flex

Let's say you have a business object which has rich getters (where the properties of the bean do not correspond directly to the columns in the database table). What is the best way of architecting your model to return the calculated values for both your Flex and HTML applications? Here are some thoughts . . . (Thanks to Jeff Tapper for his excellent intro to Flex which got me thinking about this topic)


IBO 2.0 - Return of the Iterating Business Object. Now on RIAForge!

The Iterating Business Object is the basis of almost everything I do in ColdFusion. The ability to load a recordset (or one or more structs or lists) into a single object and then to get all of the benefits of rich encapsulated getters and setters without any of the downsides just gets better and better the more you use it.

My IBO had gotten a little overstuffed with tangential concerns, but as part of a rewrite of my framework I've cut it down to its core concerns while making some improvements to its functionality (adding class properties) and I have decided to release it as a project on RIAForge - . . .


Loading Business Objects

Most of the time I want to call a method on a service class to get a loaded IBO (you know, Product = ProductService.getByID("12") or UserList = UserService.getByFilter("FirstName LIKE 'pet%'")), but for some use cases, some kind of Object.load() would be nice . . .


A composed Iterator

Paul Marcotte just posted an iterator that you can compose in your beans to provide an Iterating Business Object without having to use inheritance.

Personally, I am too lazy to write the delegates in the business object (hmmm, suppose you could generate and then mix them in if you wanted to :->), but in terms of ease of dropping into a project this is definitely a good solution and worth playing with.

A Simple Iterator - No Question!

Many thanks to all who helped with the iterator. FYI, the iterator I chose including design decisions and code is below . . .


Is Everything a Collection?

If a collection is a set of 0..n records, is it really worth hard coding the special case where n=1?

Help/Input requested!!!

Because I like writing a small amount of code that solves a large number of problems, I really don't like coding special cases unless it is necessary. For instance, many people write scaffolding forms that allow you to edit a single object using all of its fields. But what happens if you just want to change the price and title of ten products using a single form? Of course, you could hand code that, or you could just pass a property name list to your form (the fields to include in this instance) and automatically make all of your forms support editing of a collection of n-records (including the special and most common case - where n=1).

This issue has come up as I try to decide how to implement my business objects. I need to have a base business object with generic getters and setters, and I need a collection object (I used to call it an Iterating Business Object) with my updated iterating methods - first(), next() and hasMore(). . . .


More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.005.