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.next()#">
#ObjectList.get("Title")#<br />
</cfloop>
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.
Thoughts?