It's been a while since I've written about OOPhoto, my latest attempt at learning object oriented programming in ColdFusion. The problem is that I am a bit stumped as to how to proceed. The last I left, I was thinking about creating some sort of Facade layer that would handle the processing of data. Right now, the application is still very data centric - I might create objects, but I am manually stuffing data into them; I am still very much processing the data myself rather than having other object process it for me.
To solve this problem, I was thinking about creating some sort of Facade layer to the application whose responsibility it would be to process data. Something like:
<cfset arrErrors = APPLICATION.Factory
.Get( "Facade" )
ID = FORM.id,
Name = FORM.name,
Description = FORM.description,
PhotoIDList = FORM.photo_id_list
I figured by doing this, the Controller wouldn't have to know how the data was handled, it would simply pass it off to the Facade layer which would then (behind the scenes):
- Create or Load the given gallery object.
- Move the data into said object, creating any aggregated objects as needed.
- Validate the object and return any validation errors.
- Save the object.
At first, I really liked this concept for a number of reasons:
It completely encapsulates the processing of data from the Controller. This will allow us to change the processing of data with a lower likelihood of having to change the code that invokes it.
It allows the Controller to "think" in terms of "gestures" (ie. save, delete), rather than in terms of the implementation of those gestures.
It allows the Controller to translate the View naming conventions into the Model naming conventions (ie. FORM.photo_id_list becomes PhotoIDList argument).
It would cut down on duplication of code if we had two ways to update the same data in an application. Since the Controller is not implementing the processing, we can keep the processing in one place with N light-weight invocation instances.
So then I thought we could take this further an add other "processing" methods such as:
- DeleteGallery( ID )
- UploadPhoto( FormField )
Again, I like this because the Controller doesn't have to worry about creating objects - it just passes the simple form data off to the Facade which takes care of the requested, "gesture."
But then I thought about getting an object. Let's say we are on a detail page and I need to load the gallery with ID, "4." Right now, I just ask the Service object to load the gallery and that works fine. But, is this "processing" data? Should this go in the Facade? This seems like a scenario that could go either way.
And then I thought, what about all the other methods? Things like:
- Get Recently Uploaded Photos
- Search Photos
- Get Gallery By JumpCode
- Get Comments For Photo
Right now, these methods are all in the service layer and take very simple arguments. Would I move these to the Facade layer also? That seems silly right? If I did that, the Service layer and the Facade layer would start to look exactly the same.
And that got me thinking - would I want to have a Facade layer AND a Service layer? If I did, then I'd have some calls going to the Facade layer and some calls going to the Service layer with no clear reason as to why one object contains method that the other does not. And, as I hope you have seen in my previous posts, if I can't explain why I am doing it, then I better not do it.
To help answer this question, Kurt Bonnet came up with the idea of BuildInstance(). This would be a method of the Service class and could convert my simple data into a business object. This would hide some of the processing of the FORM data, but would still require the Controller to know how to use the object once it was created. I like it, but I think there is something missing.
.... so, this is where I am now. I have no idea how to proceed. I like the idea of a layer that "processes" data, but I think that is a slippery slope. On one hand, it feels a bit like moving back into the procedural mind set and on the other hand I can't come up with a rule as to what constitutes a method that "processes" data.
Maybe what I am starting to feel here is a need for a data access object or DAO. Anyone who has been programming for a while has probably seen this. A DAO generally contains CRUD methods - Create(), Read(), Update(), Delete() (or some variation of that). Could this be the place for my "processing" methods? Would this be the place to hold methods like, UploadPhoto()?
Perhaps, my next step is to think about separating my methods into those that update the system and those that do not. Basically, which gestures mutate data and which gestures simply access it. This could create a natural separation of concerns. But, would that ultimately solve any of my issues? What kind of arguments would these methods take? To hide the implementation of processing, it seems that they would have to take simple arguments, not objects. Hmmmm.
Any help would be greatly appreciated.
Want to use code from this post? Check out the license.