Builder Design Pattern In ColdFusion
Recently at work, I had been puzzling over object creation and sub-object creation within each of those objects (e.g. how do I create deep nested objects without bringing down my database server and my ColdFusion server trying to loop over everything). After checking out the design patterns books, and the good ol’ Gang Of Four (GoF) book, the solution that seemed to meet our needs the best was the Builder design pattern. This will probably just be a general overview to start with and then I’ll try to get into some of the code, and ideas I implemented to make all of this happen, and in a relatively efficient manner.
In order to create all of the objects, I wanted to have as much autonomy and encapsulation as possible, so that no parent need know how their own child objects are created…the only thing they would know is which child objects make up “themselves” (if that makes sense to anyone other than myself
). So, in order to accomplish this, all objects that need to be built start off with a director.
The director knows how to build itself and which objects it is composed of. The director (in my use of the pattern) calls other directors to build the objects that it is composed of. For example, if a User object is composed of a role object, and an organizational unit object, these would both have their own directors, RoleDirector and OrganizationUnitDirector, which would also build them, along with all of the basic properties of the User object, and return them back to the UserDirector to build all of the composed object. The basic properties of the User would be created in a Builder, the UserBuilder, which would also handle (in my case) returning identity values for attaching the role object and organizational unit objects to each User object in the director.
In order to reduce the amount of database calls, I wanted to get all of the necessary objects for all of the top level parent objects at once. For example, if I had 50 users that were being built, I wanted to query the database for role objects for all 50 users, and the same for the organizational unit objects. This way, no matter how many objects I had, the total number of database calls would be equal to the number of objects that composed the top level parent object. In this case a User with a role object and an organizational unit would be 3 total database calls (one call the get the 50 users, 1 to get the role data and 1 to get the organizational unit data). If each one of the child objects had a child object, that would still be only 2 more database calls. If I handled this as each object was being built, it would be 50 users * 3, or 150 database calls…and so on, and so on, so quite a bit of savings to the database. The only problem I then had was how to call the database without using the “WHERE…IN” statement which we’re all told to avoid like the plague, or at least try something else if at all possible.
I had chatted with our DBA to see if there was a better solution than just passing a huge list of IDs to a WHERE…IN statement and he suggested using a solution he came up with that actually parsed out the IDs from a list and places them into a table that can be joined on just like any other table. This is the method he felt would allow us to use the method described above while still keeping pretty good efficiency from the database. I’d also asked about moving to stored procedure calls which should also allow for some improved efficiency…maybe not a lot, but at least it keeps the database management contained in a central area. For testing, I kept with the WHERE…IN, but once we move to production, I’m going to push as much as possible to stored procedures with no WHERE…IN allowed
…no really good reason to keep them in the code, but several good reasons to push them out.
My final problem was when building the objects in the director, how could I access all of these objects that my other directors had created without having to loop over arrays of objects over and over again in order to get at the data I needed. As structs in ColdFusion can be called via Associative Arrays, I figured why not come up with a solution to create an associate array using some kind of value that is passed in from the calling Director, that could be used as a reference when needing a specific object from that associative array. Thus, taking a note or 2 from Flex, I created the ColdFusion ArrayCollection.
I’m going to stop now, but I’ll hopefully be able to take a few of these ideas and show how I went about creating the directors, builders, the ArrayCollection object, and perhaps even the database portion. I’ll at least go more in depth about the whole layout of things. I’m supposed to document this for work, so perhaps this will become a nice document for them to use also