I said it in a post to the cfcdev mailing list and Henry Ho felt it deserved a mention on his blog.
The topic came up because John Whish, manager of the Devon CFUG over in England (where I spoke last September on design patterns), is running a series of presentations on OO and patterns for the group. He wondered how to approach the fact that CFers tend to have separate DAOs and Gateways whereas that distinction does not exist in non-CF languages or pattern literature.
I feel responsible for that distinction so I replied with my thoughts and an explanation of why I had suggested it nearly six years ago but why I don't think it's good advice these days (and, frankly, hasn't been good advice for years - I no longer had access to the guidelines document that enshrined the advice!).
I recommend you read the thread on the Google Group (cfcdev). Henry quotes part of my reply and links to the thread for more detail.
I now work with ActiveRecord (via Rails) on a daily basis and absolutely love its simplicity. Diving into ColdBox and Transfer and back to the DAO/Bean/Gateway/Service approach just makes me want to run for the hills.
I think all this 5:1 stuff steepens the learning curve for CFers that are trying to get their feet wet using frameworks.
It's why I removed some example code (while I was still with Macromedia and had access to the source of the document). I found people just copying the example code without understanding it and then running into problems (and blaming the example instead of their lack of understanding).
At a conference several years ago, I suggested to one CFer that it would take him a few years to get good at OO - and he was incensed, accusing me of calling him stupid. I started doing OO 17 years ago and I'm still learning and still honing my OO design skills. It's a long road but a lot of people seem to think there's a shortcut, a set of rules they can learn and just churn out code without having to think.
It can get a bit frustrating at times :)
The DAO/Gateway approach is simple to understand and as such I have found that once people get something working, they just stick with it without looking at other patterns/languages or the drawback of this approach, thinking that is _the_ way to write the data layer.
It's nice to hear that others also think the same. When I first saw it been promoted by Macromedia I thought that perhaps I didn't have the depth of knowledge to understand the why of why they were doing it that way.
In the end I saw it as more work than it was worth and simply ignored it.
@Sean,
I took Hal Helms OO test and failed miserably. I've been "trying" to understand OO for over 10 years, but to be perfectly honest I start getting lost pretty early on into the detailed stuff, especially when folks start quoting the big brains who invented all of it. I wish I had the time to really read "design patterns explained" and one day I will, hopefully that will help.
Fwiw though, I never do 5:1 and I wonder if that isn't oversimplifying the issue (I can't even recall what the 5 would be honestly). The people doing straight 5:1 probably wouldn't be writing better OO without a Gateway. Despite the fact that I authored the code generator that often seems to perpetuate the problem a bit, much more thought goes into the objects and services I create than the 1 table:1 object (and n CFCs).
I built a code generator that spits out CRUD for every table in my database. It is dynamic enough to allow custom queries or simple selects. Lately I've gone to using a controller to access them but that's as far as I'll go.
FWIW, I keep my single object methods and my aggregate query methods segregated by name: getObjByCriteria(criteria) for single objects, findObjsByCriteria(criteria) for aggregate queries. Both in my ConceptDataGateway (since one gateway object usually manages persistence of a group of related entities).
As for the 5:1 problem, it's not as bad as long as your components are built around a set of related entities and not just 5 components for every table.
Could one explain why this is frowned upon in CFML?
CF's object creation is not (currently) fast enough to make that practical - 2,000 records in a query is fine, 2,000 objects in an array is "too slow".
I take the position that query in CFML is already an abstraction and the language has a number of constructs that operate natively on queries. There are aggregate operations that are *harder* on arrays of objects than on native queries. Consider the built-in tags that take a query as an attribute - you cannot pass arrays of objects to those.
So, whilst I'd *like* to see array of object be fast enough to use it for large recordsets, I think a lot else has to change in the language to make that worthwhile.
@Sean, I *definitely* agree, I do not see a problem with returning a query object in itself. I think that's a perk of the language most languages don't have to offer... I also believe languages that don't natively support query beans (if you will) have to make up the lack of support with arrays...
I say leverage CFML for what it is, rather than trying to mimic other languages DSLs...
idunno :-\
rails activerecord is the simpliest, most elegant and easy way to interact with a database. everything is contained in one class for you and it make switching between database platforms pretty painless.
i've been saying for years that adobe, and now the cf advisory counsel, needs to come up with a solution for the object creation penalty. i know it's not the function or purpose of the advisory counsel, but their influence and backing would be extremely beneficial.
However, what I do use occasionally is a "Report" or "Search" object, which I can inject ordering and filtering information into, and call a function on it to return results. This is usually separate from my DAO, since it often does Joins, subqueries and unions with other tables/information sources. I haven't really seen any documentation for this pattern, but I've found it to be very useful for generating reports and helping build user interfaces for data-mining. I never quite understood the reasoning for the Gateway object, but I suspect it was similar to my Report object.
I have written a few blog posts about what I'm about to say, but this is one of the reasons I have been known to rail against the OO community in general. Yes OO is a valuable tool. No, I don't believe that most people think outside of the box. When someone with a reputation like you, Sean, says something about OO, most of the rest of the OO "sheep" (in our little community) follow what you said.
Let me pose some deep questions: are the base OO principles that we follow today the end of the story? Will we continue to find better ways to do OO as time goes on? Will we eventually develop/find some other fundamental programming paradigm that makes OO look like pencil and paper?
I don't know the answer to any of these questions, but I think it's wise for the geniuses among us to continue to push the envelope, so to speak.
Knowledge and best practices are always evolving so that's a a bit of a silly question.
"Will we continue to find better ways to do OO as time goes on?"
Of course! I've said early and often that I started doing OO in 1992 - yes, 17 years ago! - and I'm still learning, still improving and still adapting to changes in thinking about "what's best".
"Will we eventually develop/find some other fundamental programming paradigm that makes OO look like pencil and paper?"
I don't know. In some ways OO is a radical departure from previous thinking but in many ways it's just plain common sense - procedural programming was so far removed from "how the world works" that it's amazing we ever got any systems built!
You also need to remember that COBOL was standardized as an OO language before C++ was standardized (much to the chagrin of some of us on the C++ Standards Committee). Some OO languages date back over 40 years now (but have never been standardized). Functional programming was much vaunted in the 80's as the "next wave" but it never became mainstream (although it still has a very solid following these days, e.g., Haskell). Declarative programming was another style that was very popular in the 90's but, again, never became mainstream (e.g., Prolog).
The worst thing any programmer can do is assume technology is static and that they will eventually master it. Languages evolve. Technology evolves. Thinking evolves.
ColdSpring certainly does not help the issue. A quick review of the reference PDF that comes with CS and you are already headed down the path of 5:1. Those CF developers looking to expand their OO knowledge and do so by embracing such a framework are inevitably going to spend more time focused on adhering to the implementation "guidelines" set forth in the docs, and less time considering the ramifications.
We lept on Coldspring for that reason, and the fact that we were tightly integrating with a Java-service layer which (surprise!) uses Hibernate. Suddenly, any argument against arrays-of-objects falls to the wayside.
Personally, I'm encouraged by this announcement, and plan to dig deeper.
ColdSpring itself has no bearing on the 5:1 problem (and, in fact, you'll have less work to do with ColdSpring if you have fewer services and data gateways).
Again, the problem here is people slavishly follow "simple examples" and applying them to their own code without understand the principles.
People really need to read more OO literature *outside* the CF world...
I totally agree with all that you said (in response to my comment). Obviously, some of my questions I posed were rhetorical...however, I honestly believe that some of the "sheep" I mentioned earlier don't ever think about questions like this. You do, obviously. And I do, and many others do.
But the sad thing (to me) is that most of the OO crowd (in my opinion) just reads books and follows whatever trend is hot at the moment. But this isn't unique to OO. The same thing happens in all walks of life, from the clothes we buy to the politics we believe in.
Correct, *just* the documentation. What's funny is that on one page, there is a diagram that contains an explosion of DAOs and Gateways.
Of course, CS itself isn't locked down to that model, and a new ref. guide certainly might do it wonders for the new-to-CS developer.
You can add my vote to the "read more OO literature" motion.
Returning an array of CFCs (instead of a recordset query) is the expensive part.


