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.
Looking For A New Job?
- Expert Coldfusion Developer with extensive Microsoft Media Services expertise at Atprime Media Services
- Senior CF Backend Developer at Explosive Concepts, Inc.
- AngularJS Opportunities at Top Companies. Get Better Compensation & Culture! at AngularJobs.com
- 7 plus year CF Developer to assist live website at Atprime Media Services
First let me say your examples expressed for OOPhoto are great. Good job and keep up the great work.
Now in regards to the wall you are hitting it sounds like you are on the right path. Building a factory (DOAFactory for example) could assist here couldn't it? Maybe even look into using Tansfer (not sure if you want to go that deep in your examples though)?
Here is what I have seen in the past if you want to great a window to your CRUD methods:
<cfset dao = DAOFactory.getDAO("tableName").read(ID=1) />
Am I missing something else?
Ok, so I read your post again and I think I was a little off ;-).
My instinct says to keep your data access methods within a service which can talk to the DAO factory. I think that a good path.
If you want your application to be able to build your business objects you might need your application to be more aware of what each table contains in regard to structure (db metadata). This will allow your application to be that much smarter in regards to building up your overall business objects on the fly.
Transfer keeps springing to mind in regards to helping with such metadata.
Right now, I want to try to avoid all frameworks. I am currently trying to figure out what my problems are and how to solve them. I am not sure that using something like Transfer would help.
As far as the meta data for tables, this is not a concern. I am hand-coding everything so any function that needs to read from or update the database has all the meta data it needs stored in this big, sexy brain of mine :)
I'd love to get your thoughts on the idea of form data processing, which is one of my biggest hurdles right now. In your OOP apps, who processes your form data?
One way I would process a form would be to create DataAccessService (can contain your validation type methods/classes references as well as give you functionality to pass back a BO object after it has gathered data from the factory) that ties to a DAOFactory which would pull a specified DAO from the associated form submitted BO folder (photo, etc). The form would supply the flag specifying which BO is being worked on (photo, etc) so the factory knows what to do and the fields would represent either bean variables (accessors) or CRUD method arguments (so you can just pass the form collection).
So it would look something like this (process):
form -> BO Controller -> BO Service -> DataAccessService (validation, BO creation) -> DAOFactory
BTW I am happy to help work something like this into your app with you if you'd like.
You can also move some of those common methods (example: LoadObjectsFromQuery) to the DataAccessService and make them one off helper methods which can be called after your BO Service retrieves that data. Simply pass in the query and BO type and the helper should be able to cycle through the query and build the object or collection you are asking for.
With a few minor adjustments this could save you some time and code space.
I'm wondering if you are getting bogged down in terminology, e.g. Controller vs. Facade.
When I see Model-View-Controller, I think of an architectural approach. Where each component could be multiple objects.
When I see DAO, Facade etc, I think of common types of objects that may exist in each component or my architecture.
So I don't know if your question should be controller and/or facade? but perhaps,
do you want to have a facade object as part of your controller?
I personally like facade objects as the receiving object for form data (in many case one facade can receive input from multiple forms), or any other user requests to (e.g. a batch submit). Abstraction is the main reason.
I just posted some more thoughts on your previous blog post. It's a bit large, hopefully there's something useful in there :)
I definitely think that the terminology gets a bit confusing, especially when I am doing some stream-of-consciousness type of thinking that involves barfing a lot of stuff onto the page.
I am not sure I completely understand what you are saying about the separate parts of your application; however, I think we end on the same point - it is nice for a Facade to handle the FORM data. That is something that I have been leaning towards, but am having trouble fleshing out the WHY's and HOW FAR's of it all.
Can you explain a bit further about the idea of a Facade being part of the Controller? I have not heard of this before.
It's almost 9pm, so I am having a bit of trouble following along with everyone - I apologize - but from what you are saying, it sounds like you are relying on many naming conventions. For example, are your query column names and your object properties all spelled the same? Are your form fields and your object properties all spelled the same? These are the red flags that I see in my mind when people talk about just passing the FORM "collection" around.
Thanks for offering help - as you can see, I am really struggling to wrap my head around all of this :) Your feedback is hugely appreciated.
Honestly, while writing aspects of my recent post above I did see the flag waving in the distance :). But I pushed it out there anyways to get your opinion. :)
I'm use to this approach with some sort of added security in mind. So to answer your questions "yes" the idea was to push the properties/column in as references for simple binding logic.
It's late here now too and I just got back from doing a CVS preso so I am going to keep this short :). I am going to sit tight and see how you push the facade into the mix. I am quite interested and if anything can help security more then great.
BTW. We talked about this in our Sacramento CF User Group today as we want to get more developers involved with OOP around here.
Have a good night Ben.
Yes the Facade and Service layers do tend to have the same public interface - but the Facade might care about things like security and exception reporting that the Service layer does not.
Handling security is whole OTHER mess that I'm not nearly ready to tackle :) Stop trying to scare me! However, that is a very interesting idea to play with - the idea of a Facade not just simplifying a set of features but providing additional aspects of processing that the service layer simply doesn't account for.
Along those lines, I suppose you could have a Facade layer handle logging as well.... and perhaps audit tracking.
Not that I am nearly experienced enough to get into this, but are we starting to think about "Decorators" when we talk about this type of tack-on-functionality?
... no, not ready to open up a whole new can of worms; let me muddle through the basics first before we get into the next level of thinking.
Good luck with your CVS presentation.
'but are we starting to think about "Decorators" '. I wasn't, but I could mention 'Aspects' - as in Aspect Orinated Programming, as in AOP, as in ColdSpring. Does what you think it does 'providing additional aspects of processing'.
There is an example here : http://www.rachaelandtom.info/building-coldfusion-services-6
Hopefully someone will give a good talk on AOP soon...
This is way out of my league - I must learn to crawl before I can learn to walk :)
@I've decided to move ahead with a Facade layer:
I need to do something and I figured this would be an OK next step.
For you question
Can you explain a bit further about the idea of a Facade being part of the Controller? I have not heard of this before.
It may just be my use of the term Controller.
I think Controller in the context of the Model-View-Controller architectural pattern, not a design pattern.
So I think of a Controller as a collection of objects that share the common purpose of "controlling" the application. So a facade is just one of the objects that my controller will typically have.
To put this in context, I also have a facade object as the as part of my Model. (to give my Controller a stable interface to talk to the Model through)
So I'm not sure if we are using the term in the same way.
You might want to look at
It seems to use the term more along the lines of what you are doing/looking for.
It looks like I am using it for the latter of your use cases:
"To put this in context, I also have a facade object as the as part of my Model. (to give my Controller a stable interface to talk to the Model through)"
I'll take a look at the J2EE design patterns link, thanks.