I think you touched on a key point, which is to read books/references and not looking for "the answer" because it doesn't exist. OOP is very iterative and "the answer" always depends on your situation which is why people on the list will often respond "well, it depends...". Read as much as you can so you have some knowlege to pull from when you go to implement, then implement something, then see what can be improved and make changes/refactor and repeat. Posting to the list between iterations of course ;)
-Phil
On 12/15/05, Ben Nadel <[EMAIL PROTECTED]> wrote:
Nando,
Thank you very much for the extensive explaination. Its all getting clearer
every day. Last night I went to Barnes&Noble and read the first 70 pages of
the Design Patterns Explained (2nd Edition). It seems pretty good. The only
think that confuses me is that he'll write examples - which I try to absorb
with a sponge-like fashion - and then at the end, he'll be like "And later
we'll see why this approach is very limiting" and I'm like "D'oh! Cause now
I've looked at it like it's the answer :)" But I will see if I can get a
used copy somewhere. $50 for a small book seems a bit crazy.
I see what you are saying about the bean for the display page. At first I
figured that it would make so much sense since the GET methods would be so
organized for display. But if you are not updating, a query object is
actually easier to work with perhaps and requires far fewer method calls.
Thank you so very much!
......................
Ben Nadel
Web Developer
Nylon Technology
6 West 14th Street
New York, NY 10011
212.691.1134
212.691.3477 fax
www.nylontechnology.com
"Vote for Pedro"
-----Original Message-----
From: [EMAIL PROTECTED] [mailto: [EMAIL PROTECTED]] On Behalf
Of Nando
Sent: Thursday, December 15, 2005 5:13 AM
To: [email protected]
Subject: RE: [CFCDev] Object relations, getting, setting, and validation Oh
My!
Ben,
Well, let's think about it a moment.
A bean gives you the ability to get and set individual properties. What
properties do you need to set() when displaying a page detailing a
publication? I'm not saying anything universal here, but in this particular
case, does the ability to get and set particular properties help us to get
the job done. Probably not. A gateway does it best, and can do it very
efficiently.
Now here's where composition can come into play and be very useful to
efficiently display pages. Let's say we use a Factory to instantiate the
gateways we need for display. Instead of instantiating our gateways every
time we display a page which would be a little inefficient, and who knows,
you might need multiple gateways to display a page, let's create a factory
as a singleton when our application starts up, instantiate it into
application scope, and in it's init() method, instantiate every gateway
we'll ever need to display pages, and keep them in the variables scope
within Factory.
What you get then is a set of instantiated gateways composed into Factory,
hanging out in memory, instantly available to the application.
(this code sample assumes all CFC's are in one directory, which allows you
to use the returntype without a specifying a path)
<cfcomponent displayname="GatewayFactory">
<cffunction name="init" access="public" returntype="GatewayFactory"
output="no">
<cfargument name="dsn" required="Yes" type="string" />
<cfset variables.dsn = arguments.dsn />
<cfset setPublicationGateway( variables.dsn) />
.... (add any other gateways here) ...
<cfreturn this />
</cffunction>
<cffunction name="setPublicationGateway" returntype="void" access="private"
output="no">
<cfargument name="dsn" required="Yes" type="string" />
<cfset variables.PublicationGateway =
createObject('component','PublicationGateway').init( arguments.dsn) />
</cffunction>
<cffunction name="getPublicationGateway" returntype="PublicationGateway"
access="private" output="no">
<cfreturn variables.PublicationGateway />
</cffunction>
.....
</cfcomponent>
Now all of your gateways are instantiated and held in memory - which can
improve performance considerably.
So to display that page, you'd call
application.gatewayFactory.getPublicationGateway().findPublication(someId)
and not
publicationBean.getPublicationGateway().findPublication(someId)
We're using composition to implement an architecture that helps us get the
job done and do it well. But it's from an *implementation* perspective, not
a *conceptual* perspective. You won't find a GatewayFactory in your
conceptual model.
*****
When editing a publication, being able to instantiate your PublicationBean,
set() the initial values, get() them to populate your form, set() them again
when the form is submitted, get() them to validate each that need to be
validated, perhaps selectively, perhaps each in different ways, and then
depending on how the validation goes, either pass the bean to your DAO and
get() the values again to persist them, or get() the values to populate the
form again with your error message ... is all very useful. All those getters
and setters really help to get the job done. The Bean encapsulates the data
for you, so you can work with it. In this case, practically, from the
implementation perspective, a bean is very useful when editing.
Now, there ARE cases when you might be editing a composed entity all in one
go. Here's an example. I'm often building sites in multiple languages. Pages
can have properties which are universal, like it's location in the
navigational hierarchy or it's template, but they also have properties which
are language specific: title, meta tag, navigational label. So what i do in
this case is instantiate an array of language specific PageLanguage beans
inside a Page bean, and the code for the form loops through the array of
PageLanguage beans and generates the fields on the fly and populates them.
The difference here is that it's all edited in one form, so to implement it,
composing those PageLanguage beans into the Page bean helps me to
encapsulate the data necessary for that, validate it, and persist it.
So yes, it's definitely possible that you'll need to compose a bean or
several beans within another when editing an entity, but i'd use it only if
the capability that a bean gives you, all the gets() and sets(), the
encapsulated data, helps you to get your job done.
If you try and implement a model that follows a conceptual perspective,
it'll most likely wind up to be much more complicated than necessary.
"Let's see ... a Publication has a Category and a Category has Publications
and a Publication has an Author or actually an array of Authors ... gee, how
do i build that? Do i need a separate object called Authors to contain the
array of Authors composed into Publication composed into Category? Or are
Categories composed into Publication, because a Publication has a Category?
Or maybe it's both? How do i do THAT? And what about Department? Departments
have Publications and Authors, but sometimes Authors are in multiple
Departments ..."
You take a few steps down that path and you don't know where to draw the
line.
Somebody comes along and says "Just use a gateway and in the find() method,
use a join to get the category and author data" and it seems too simple.
Like they are probably cheating. ;) They aren't. They are just looking at
the model from an implementation perspective and doing what makes sense.
Don't worry. There will be plenty of opportunity to use the power of OO once
you get into it a little deeper. At least that's what i'm finding.
Nando.getToWork(Now('ummm ... can have a coffee first?'))
PS ... i know, i know, Now() doesn't take any arguments, but i argue with it
anyway! ... ;o)
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email.
CFCDev is run by CFCZone ( www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com).
An archive of the CFCDev list is available at www.mail-archive.com/[email protected]
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email.
CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com).
An archive of the CFCDev list is available at www.mail-archive.com/[email protected]
