A disclaimer up front – I am not sure if this pattern is specific to ColdFusion, but I have never seen it in another object oriented language before.
A design pattern is a template solution for how to address a common issue in object oriented development. So here is a problem. In an ideal object oriented system, you are dealing with a server that never goes down and has unlimited memory. Therefore, when your application has five thousand user accounts, you just have five thousand little user business objects floating around in memory waiting to be used. In reality this is not really practical.
So here is the dilemma – you want to stay true to object oriented practices and benefit from the use of business objects, but trying to create a business object for every user record in the database just to display a list of users is not really practical. At the very least, the current request will be very slow and at worst, if it is a common request, you could bring the server down trying to do that kind of object initialization and garbage collection.
Some time back, I was introduced to the concept of an iterating business object (IBO) by Peter Bell. Simply put, the IBO is a business object with all of the desirable object oriented characteristics – getter and setter functions, data encapsulation, etc. However, instead of just containing the data for a single record, it can contain one or more records. Therefore, when you need to deal with a collection of user records, instead of creating a new business object for each user record, you can create one single user IBO instance and load all of the user records into the one object instance.
Internal to the business object, each record is now stored as a structure within an array. The business object maintains a pointer to the “current” record and has a variety of infrastructure functions to manage this array of structures. These functions include:
- add() – this function adds a new record (array element) to the business object and updates the current record pointer to point to the new record, leaving it ready to be populated.
- asQuery() – this function takes the internal array of structures and converts it to a ColdFusion query object which is returned. This is useful for serializing the result to JSON or for other display purposes.
- asStruct() – this function returns the current record as a structure. While returning records as structures looses the benefits of the object oriented business object, it can still be useful on occasion.
- currentRecord() – simply returns the current record number being pointed to by the record pointer.
- get( propertyName ) – a generic getter style function which will retrieve the value associated with the specified property for the current record. By using onMissingMethod(), this function can easily respond to the traditional getPropertyName() function call as well.
- loadQuery( queryObj ) – accepts a ColdFusion query object and loads it into the iterating business object. This is useful when using a DAO to quickly load multiple records into a business object at one time.
- loadStruct( structObj ) – accepts a ColdFusion structure and loads it into the current record of the iterating business object. This is useful for loading data like form submissions into a business object in that you can pass the entire form scope into the function at one time.
- next() – advances the internal record pointer to the next record. This function is very useful in looping through an iterating business object.
- recordCount() – returns the total number of records in the iterating business object.
- reset() – resets the current record pointer to point to the 0 record. This in combination with the next() function makes it very easy to loop through an iterating business object.
- set( propertyName, propertyValue ) – a generic setter style function which will set the specified value for the specified property for the current record. Again, by using onMissingMethod(), this function can easily respond to the traditional setPropertyName( value ) function call as well.
In another post, I will show some examples of how we have been using this functionality in our latest project as well as how we have encapsulated this functionality into a base object that all of our business objects extend, making it very simple to add new business objects to the system.
If you would like to learn more about object oriented development, and more specifically object oriented development with Model Glue, we have training opportunities that are coming up next month with early registration ending Wednesday. In addition, feel free to contact us to see how we can help with your next project.