The DAO and Gateway separation in CFML is nonsense
March 3, 2009 · 31 Comments
There, I said it!
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.
Tags: architecture · coldfusion

31 responses so far ↓
1 Cody // Mar 3, 2009 at 9:55 PM
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.
2 Sean Corfield // Mar 3, 2009 at 10:20 PM
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 :)
3 John Whish // Mar 4, 2009 at 12:42 AM
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.
4 Gary Gilbert // Mar 4, 2009 at 1:19 AM
I always found it serious overkill and tended to delete the gateways when using the wizard to generate code.
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.
5 bri // Mar 4, 2009 at 2:03 AM
6 Brian Rinaldi // Mar 4, 2009 at 4:57 AM
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).
7 John C. Bland II // Mar 4, 2009 at 7:10 AM
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.
8 Sean Corfield // Mar 4, 2009 at 8:27 AM
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).
9 Tony Nelson // Mar 4, 2009 at 9:14 AM
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.
10 Sean Corfield // Mar 4, 2009 at 10:17 AM
11 salomoko // Mar 4, 2009 at 10:42 AM
Could one explain why this is frowned upon in CFML?
12 Sean Corfield // Mar 4, 2009 at 10:59 AM
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.
13 Brian Rinaldi // Mar 4, 2009 at 12:21 PM
14 salomoko // Mar 4, 2009 at 2:06 PM
@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 :-\
15 Sean Corfield // Mar 4, 2009 at 2:32 PM
16 tony petruzzi // Mar 4, 2009 at 3:39 PM
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.
17 Sean Corfield // Mar 4, 2009 at 3:56 PM
18 John C. Bland II // Mar 4, 2009 at 4:01 PM
19 Adam Ness // Mar 4, 2009 at 7:08 PM
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.
20 Jake Munson // Mar 4, 2009 at 10:56 PM
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.
21 Sean Corfield // Mar 5, 2009 at 12:21 AM
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.
22 Shawn Holmes // Mar 5, 2009 at 3:44 PM
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.
23 Sean Corfield // Mar 5, 2009 at 3:53 PM
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...
24 Jake Munson // Mar 5, 2009 at 5:01 PM
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.
25 Shawn Holmes // Mar 6, 2009 at 6:26 AM
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.
26 Jeff Battershall // Mar 20, 2009 at 3:14 AM
27 Sean Corfield // Mar 20, 2009 at 11:20 AM
Returning an array of CFCs (instead of a recordset query) is the expensive part.
28 Sean Corfield // Mar 20, 2009 at 11:22 AM
29 Sean Corfield // Aug 24, 2010 at 11:08 AM
"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). "
Interestingly, functional programming seems to be having a massive resurgence these days, with Scala, Clojure, Erlang and F# all becoming more popular (and other, more niche functional languages also getting press).
So, technology and the problems it solves have already evolved and changed the way quite a few people are thinking about software!
30 Daniel Budde // Aug 25, 2010 at 6:32 AM
First off, I would like to get a better understanding of the '5:1' and understanding the original idea of what should have been in each of the 5 (bean, dao, gateway, service, ?). Mainly, I have been reading a lot about these, but I still lack the understanding of what each ones function was supposed to perform. I understand each of these may not be the solution going forward (especially from your discussions above and because ORM probably removes some of the need for some of these objects). So, I guess my question for this part is, can any of you point me towards any posts/literature that explains the idea behind these? I'm hoping by asking this, this might help some others in my position so we do not become sheep.
If any of you would like to recommend a model to follow for the architecture that I will be using, I'd be happy to point my ears at you and learn more.
Any recommended OO books? I saw 'design patterns explained' mentioned above. Is this a good book to start with?
31 Sean Corfield // Aug 26, 2010 at 3:19 PM
That explains the ideas behind layered architectures and how different combinations of domain object (bean), data access layer (DAO or gateway) and orchestration (service, controller) lead to solutions with different trade offs in terms of maintainability and extensibility.
Leave a Comment