On 3/1/06, RADEMAKERS Tanguy <[EMAIL PROTECTED]> wrote:
> This whole diatribe of mine isn't about never writing
> another getter or setter in your life: it's about only writing getters
> and setters where you really need them...

I'd agree with this.

> which is to say probably
> writing 90% less than you do today.

This is such a broad generalization as to be relatively meaningless to
the discussion.

> The whole "use public accessors to
> get or set private data" is _the_ OO 101 example, page one, paragraph
> one - but most people seem to read that as "provide public accessors for
> ALL private data fields" which is wrong because you might not need to
> access those fields.

Well sure, if you don't need access to it outside the object, then you
wouldn't write a getter for it.  Why would you?  Maybe you've
personally seen people blindly writing getters for everything, but
obviously even in a bean if there's data that's private to the object
you wouldn't throw a getter in there "just because."  That doesn't
prove getters are bad or even overused.  If you need them you need
them, if you don't you don't.

> Firstly, why does an outside object have to know about the components of
> an address? Why is hiding how you do something so important, but hiding
> what something is made of less important?

Because another object in the system might need to use the address
object.  If nothing else in the system needs to know anything about
the address object, how exactly is it getting used?

> Secondly, do you agree that the acid test of coupling is how many
> objects do you have to modify to effect any given change in a system?
> Because if so, overuse of getX() is going to lead to having to change a
> lot of places when Street changes...

The equivalent of changing getStreet() to getStreetAddress(), or even
changing the datatype it returns, would really be an API change. 
Changing how getStreet() works behind the scenes is no big deal.  As
such, I don't see how getters are any worse in this case than any
other method in your system.  If you change the API you have to change
the objects that use the API.  In real-world scenarios this happens
pretty darn infrequently.

> Now let's put this in context:
> imagine you need to make a change to the street variable:

What kind of "change" specifically?  This is too generic to make sense
to me.  I assume you mean the datatype it returns?

> - horrorshow: search through all your code... cfm, cfc, inc, whatever,
> and look for getStreet() and setStreet() calls, then figure out what you
> were doing with the value of street there, and how that may have to
> change now... many cigarettes, much coffee.. and you will miss some.
> - best you can hope: you make your changes in a small, well known number
> of places, and you go to bed confident that you have got them all.

Again, this would be *if you change your API*.  As for changing them
in a well-known number of places, I can't possibly imagine you'd have
an unmanageable number of getStreet() calls everywhere because if you
do, there's something wrong with the design of the application.  And
in reality, isn't finding all these instances what your IDE's search
function is for (which you'd use in either of the two cases above)?

Furthermore, when you make a change that impacts more than one part of
the system you're going to retest thoroughly anyway (I'd hope).  You
describe the situation as if you're going to have to go line by line
through all your files and hope you find everything manually before
you throw it out into production and pray you found everything.  If
making a change to your application truly turns into a horror show,
that's the fault of the design of the app, not of getters and setters.
 In short, I see "best you can hope" above as the situation I'm in
with my apps in which I use getters and setters in all my beans (for
the data that needs to be publicly accessible).  I haven't once found
myself in a situation where I wind up in the "horror show" category
and start damning the fact that I used getters and setters.

> If something else in the system really needs to know the value of the
> street, then you implement the getStreet() method (although i would
> fight long and hard to define "really needs to know"). My argument is
> about what comes first: the getter or the need for a getter? In many
> cases today, people are blindly implementing the getter without a true
> need, in a kind of "OO checklist mentality", and then abusing the getter
> to treat an object as little more than a data structure.

I think this gets to the crux of the argument, namely how smart or
dumb bean objects should be.  I fall into the "pretty dumb" camp so
we'll likely never reach a point of agreement here.  The purpose of a
bean in my mind is to serve as an encapsulation of data, but even at
that I'd argue it's well beyond "little more than a data structure."

> >What sets off warning bells in my mind is having an address object
> >know how it's going to be displayed.  Your domain model objects
> >shouldn't know or care how they're going to be displayed.
> >
> So put that code in a renderer object!
> You would never consider
> sprinkling an object's CRUD code all over your application, but
> <cfoutput><b>#address.getStreet()#</b></cfoutput> is fine?

CRUD and getStreet() aren't equivalents, so you can't compare them as
such.  To me any time you have <cfoutput> you're in your view.  That's
view "logic" if you want to think of it that way, so if I need my view
to display the street address, I see absolutely nothing wrong with, in
my view, doing what you show above.

I think the problem I'm having with your argument is that you're
outlining such an outlandish scenario to make your point, and if the
tenets of your argument were true, that's just bad application design
regardless of how you feel about getters.  Let's say by some stretch I
find myself having to change the datatype returned by getStreet(). 
Where do I have to update my code?  Everywhere I have getStreet(),
meaning (likely) one or maybe two view pages, and maybe in my DAO as
well.  That'd be about it.

> And before
> you tell me that that exact code would likely appear in my renderer
> object, let me preempt you by saying that i know, that you will probably
> be passing in some kind of bean made up of little else than getters and
> setters to the renderer (although... memento!, but that's another day),
> and that (icing on the cake) - that's the ONLY place it would appear.

I'd think you'd have to have it in your DAO as well, so it sounds like
at best by using a renderer object you're saving yourself having to
change the code on the small number of views that use it.  To me
"renderer object" is a bit of an oxymoron to begin with so I don't see
the point really.  In my mind views are relatively throw-away, and
aside from using the DRY principle in them, I certainly don't lose
sleep over them.  By the time I hit my view I've built up everything I
need on the business logic side of the application and I'm just going
to display things, so changing view code is trivial.  (Just to take
this a step further, what if you change your renderer object?  You
have to find everywhere that's used and change it, hoping you find
everything, no?)

If I have to change two views vs. one "renderer object," I'll take the
former.  Personal preference I suppose.

Matt
--
Matt Woodward
[EMAIL PROTECTED]
http://www.mattwoodward.com


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to 
cfcdev@cfczone.org 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/cfcdev@cfczone.org


Reply via email to