Using private getters v instance data

33 views
Skip to first unread message

John Whish

unread,
Feb 15, 2010, 9:44:47 AM2/15/10
to CFCDev
Hi,

Just wondering what people consider to be best practice when writing
CFCs in terms of getting instance data internally.

For example if I have the following:

<cfcomponent>
<cffunction name="init">
<cfargument name="foo" required="false" default="1234">
<cfset instance.foo = "arguments.foo>
</cffunction>

<cffunction name="timesTen">
<cfreturn instance.foo * 10>
</cffunction>
</cfcomponent>

Would you create and use a private getter and setter for mutating
"foo"?

The way I see it is that using getters and setters internally means
that you can add extra functionality such as type checking etc, the
down side is extra code.

Equally, if you have a public getter for "foo", should you then use
the getFoo() method in your instance code? Again the downside to this
is that you might have a getFoo() method, but not a getBar() method,
so you'd end up with inconsistent code.

Not a ground breaking question, just curious to know what people
think!

Thanks,

- John

Bob Silverberg

unread,
Feb 15, 2010, 9:59:53 AM2/15/10
to cfc...@googlegroups.com
I think this debate comes up from time to time and, for the most part, it comes down to personal preference. I used to use getters for everything - never referring directly to variables.foo or instance.foo.  I think that there could be advantages to that extra encapsulation, as you suggest - it means that something other than simply "return instance.foo" could happen inside getFoo() and one could change that implementation without worry.

On the other hand, I'd venture to say that 99% of the time nothing else is going to happen inside getFoo(), so you haven't really bought yourself any benefit.  It may be a case of YAGNI. Also, using getFoo() does add a performance hit, although negligible I'm sure.

Now that I've started using CF's Hibernate integration, where all properties are stored in variables.xxx, I've actually moved to just referring to the variables rather than calling the getters. A lot of that is out of laziness, as with CF's "implicit" getters you actually have to use this.getFoo(), rather than simply getFoo(), and I don't like having to add "this" to the call. So, to be consistent, I now tend to refer directly to any internal variables, rather than calling getters.

You raise a good point about when you have a public getFoo() method. The fact that it's public means that other components are making use of it and therefore encapsulation becomes more important. I think that consistency is important, so if you were to choose to use getFoo() to refer to it, I'd think that you should probably use getBar() as well, even if it means having to introduce a getBar() method (based on your example below). 

Cheers,
Bob



--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.




--
Bob Silverberg
www.silverwareconsulting.com

Hands-on ColdFusion ORM Training @ cf.Objective() 2010
www.ColdFusionOrmTraining.com


Dan Wilson

unread,
Feb 15, 2010, 10:06:24 AM2/15/10
to cfc...@googlegroups.com
 In the case of the code you posted, I would probably not create a setter at this this time because you have no public responsibilities for foo and the component isn't referencing foo anywhere else but the public method timesTen().

If either you chose to expose the variable foo to the public, or used a few more internal references to foo, then I might add a setter or a getter, whichever was appropriate, so the foo variable would have a mutation hook.

In my world, we should keep things simple, but not too simple. Encapsulated, but not too encapsulated. Strive for the mixture that makes sense and is reasonably future proof.

Should you implement the pseudo component as you wrote it, and later find a reason to make a setter, it is an easy refactor. Leaving yourself easy refactors for expansion is certainly much better than hard refactors, or an overly abstract component.


DW
“Come to the edge, he said. They said: We are afraid. Come to the edge, he said. They came. He pushed them and they flew.”

Guillaume Apollinaire quotes

David J Henry

unread,
Feb 15, 2010, 6:11:47 PM2/15/10
to CFCDev
ColdFusion 9 introduces implicit getters and setters with
<cfproperty>. Is it possible to make private properties with an
implicit get/set?


On Feb 15, 10:06 am, Dan Wilson <sipac...@gmail.com> wrote:
>  In the case of the code you posted, I would probably not create a setter at
> this this time because you have no public responsibilities for foo and the
> component isn't referencing foo anywhere else but the public method
> timesTen().
>
> If either you chose to expose the variable foo to the public, or used a few
> more internal references to foo, then I might add a setter or a getter,
> whichever was appropriate, so the foo variable would have a mutation hook.
>
> In my world, we should keep things simple, but not too simple. Encapsulated,
> but not too encapsulated. Strive for the mixture that makes sense and is
> reasonably future proof.
>
> Should you implement the pseudo component as you wrote it, and later find a
> reason to make a setter, it is an easy refactor. Leaving yourself easy
> refactors for expansion is certainly much better than hard refactors, or an
> overly abstract component.
>
> DW
>

> >> cfcdev+un...@googlegroups.com<cfcdev%2Bunsu...@googlegroups.com>


> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/cfcdev?hl=en.
>
> > --
> > Bob Silverberg
> >www.silverwareconsulting.com
>
> > Hands-on ColdFusion ORM Training @ cf.Objective() 2010
> >www.ColdFusionOrmTraining.com
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "CFCDev" group.
> > To post to this group, send email to cfc...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > cfcdev+un...@googlegroups.com<cfcdev%2Bunsu...@googlegroups.com>

Mark Mandel

unread,
Feb 15, 2010, 7:21:23 PM2/15/10
to cfc...@googlegroups.com
On Tue, Feb 16, 2010 at 10:11 AM, David J Henry <david...@coldfusionpowered.com> wrote:
ColdFusion 9 introduces implicit getters and setters with
<cfproperty>.  Is it possible to make private properties with an
implicit get/set?

You actually can't, which is kind of irritating.

There is a bug for it here (I think there may be more)
http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html#bugId=76132

Make sure you vote for it!

Mark

--
E: mark....@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com


Hands-on ColdFusion ORM Training @ cf.Objective() 2010
www.ColdFusionOrmTraining.com/

John Whish

unread,
Feb 16, 2010, 8:22:35 AM2/16/10
to cfc...@googlegroups.com
Thanks for the feedback, I was curious to see if there was a general consensus. 

I'm pretty sure that you don't need to prefix calls the implied getters and setters in CF9 with this. You did in the CF9 beta, but I think they changed that for the final release. I'll check that and report back when I get the chance!

I used to always have getters and setters, as it feels like better encapsulation, however my classes ended up having a bunch of "dumb" get/set methods so accessing the private instance variables scope directly seems like the pragmatic way to go. I did consider using onMissingMethod, but that adds overhead and you do have to prefix with this.

- John

Bob Silverberg

unread,
Feb 16, 2010, 9:21:20 AM2/16/10
to cfc...@googlegroups.com
Holy crap, you're right, John!  You don't need to use "this" to call an implicit method internally. I guess my belief that that was necessary came from the original beta, as you suggest.

Thanks for opening my eyes,
Bob


--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.

John Whish

unread,
Feb 16, 2010, 9:48:28 AM2/16/10
to cfc...@googlegroups.com
Cool! I only found that out as I was giving someone a tour of the new CF9 features and was waiting for it to throw an error because they hadn't used "this." and it worked! :)

Adam Haskell

unread,
Feb 24, 2010, 2:37:27 PM2/24/10
to cfc...@googlegroups.com
These are the types of discussions that show the biggest weakness in CFML, the IDE. The answer is simple in most languages, use direct access until you need to wrap functionality around it. Most of the time this is a really simple refactor in an IDE. Even without refactor capabilities it's a pretty easy search/replace so I still go with that mentality. 


Adam 

Jared Rypka-Hauer

unread,
Feb 25, 2010, 8:21:55 AM2/25/10
to cfc...@googlegroups.com
I think they fixed that in like beta 2 or something... Bob, you should try to keep up a bit more. ;) Just teasing.

That said, I always find it entertaining when I make some pronouncement about how CF needs this or that to work right and someone runs code that shows me up... it reminds me that nobody really knows everything (despite their insistence to the contrary heh).

As for the original question, in theory I find myself preferring to use instance data over getters, especially private getters... and yet the OCD side of me can't stand having a setter without its getter, and if there's a method I must call it rather than referring to variables directly. ;) So in practice I end up using private getters.

The performance hit for them is minimal, I have an Eclipse snippet for generating the get/set pair almost instantly, and in the long run having that getter there makes it much easier to refactor since you can just change the getter without having to change a bunch of references too. I "get" the idea of using instance data directly, it just doesn't sit as well as the alternative...

J

On Feb 16, 2010, at 8:48 AM 2/16/10, John Whish wrote:

Cool! I only found that out as I was giving someone a tour of the new CF9 features and was waiting for it to throw an error because they hadn't used "this." and it worked! :)

On 16 February 2010 14:21, Bob Silverberg <bob.sil...@gmail.com> wrote:
Holy crap, you're right, John! ...

John Whish

unread,
Feb 25, 2010, 8:42:42 AM2/25/10
to cfc...@googlegroups.com
Hehe - great reply!

I really don't like seeing code like:

totalcost = instance.basecost + getBookingFee();

where I have an existing public getBookingFee() method but no getBaseCost method, so I end up creating getters and setters via a snippet. Good to know you have the same dilemmas as me :)


--

Jared Rypka-Hauer

unread,
Feb 25, 2010, 9:29:19 AM2/25/10
to cfc...@googlegroups.com
Heh, thanks!

Yeah, for my snippet I type gs-ctrl-j, the stem of the methods (i.e. the name without the get/set part), the output attribute (which defaults to false) and the type (string, query, etc). I hit enter and I have a get/set pair all done. w00t!

I used to use instance data because I hated typing getters and setters, but that snipped sort of made it a moot point and I started going for more consistent code. Kinda goes to show how priorities change with the tools available to do the job, eh?

J

Nando .

unread,
Feb 25, 2010, 10:19:38 AM2/25/10
to cfc...@googlegroups.com
Jared,

Would you mind posting that snippet?

Nando

--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.




--
Aria Media Sagl
CP 234
6934 Bioggio
Switzerland

+41 (0)91 606 6372
+41 (0)76 303 4477 cell

Jared Rypka-Hauer

unread,
Feb 25, 2010, 10:36:15 AM2/25/10
to cfc...@googlegroups.com
Sure, np:

<cffunction name="set$${name}" access="public" returntype="void" output="false">
<cfargument name="$${argument name}" type="$${type}" required="$${required:true|false}">
<cfset variables.$${argument name} = arguments.$${argument name} >
</cffunction>
<cffunction name="get$${name}" access="public" returntype="$${type}" output="false">
<cfreturn variables.$${argument name} />
</cffunction>

J

On Feb 25, 2010, at 9:19 AM 2/25/10, Nando . wrote:

Jared,

Would you mind posting that snippet?

Nando
On Thu, Feb 25, 2010 at 3:29 PM, Jared Rypka-Hauer <armcha...@gmail.com> wrote:
Heh, thanks!

Yeah, for my snippet I type gs-ctrl-j, the stem of the methods (i.e. the name without the get/set part), the output attribute (which defaults to false) and the type (string, query, etc). I hit enter and I have a get/set pair all done. w00t! ...

Dan Wilson

unread,
Feb 25, 2010, 10:37:38 AM2/25/10
to cfc...@googlegroups.com
Here is bascially the same snippet with the types set for typeahead:

<cffunction name="get$${Variable}" access="public" output="false" returntype="$${Return Type:any|array|binary|boolean|date|guid|numeric|query|string|struct|uuid}">
<cfreturn variables.instance.$${Variable} />
</cffunction>

<cffunction name="set$${Variable}" access="public" output="false" returntype="void">
<cfargument name="$${Variable}" type="$${Type:any|array|binary|boolean|date|guid|numeric|query|string|struct|uuid}" required="true" />
<cfset variables.instance.$${Variable} = arguments.$${Variable} />
</cffunction>





--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.



--

Jared Rypka-Hauer

unread,
Feb 25, 2010, 10:42:22 AM2/25/10
to cfc...@googlegroups.com
Sweet... I always meant to go back and do that and I never quite got around to it.

Funny... it'll default to any, which is right, but it's also alphabetical.

J

Dan Wilson

unread,
Feb 25, 2010, 10:55:05 AM2/25/10
to cfc...@googlegroups.com
I've got the one for CFQueryparam set up the same way:

<cfqueryparam value="##" cfsqltype="cf_sql_$${CF SQL Type:bigint|bit|blob|char|clob|date|decimal|double|float|idstamp|integer|longvarchar|money|money4|numeric|real|refcursor|smallint|time|timestamp|tinyint|varchar}">




--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.

Nando .

unread,
Feb 25, 2010, 11:09:04 AM2/25/10
to cfc...@googlegroups.com
Thanks Jared and Dan!

Jared Rypka-Hauer

unread,
Feb 25, 2010, 11:22:45 AM2/25/10
to cfc...@googlegroups.com
NP. It makes life a helluva lot easier.

Cool thing: This snippet will work in either Builder or CFE.

J

Nando .

unread,
Feb 25, 2010, 11:24:51 AM2/25/10
to cfc...@googlegroups.com
Nuther dumb question. How do the trigger texts work for snippets. I would RTFM but I have no idea where it is or if it even exists.

Jared Rypka-Hauer

unread,
Feb 25, 2010, 11:27:29 AM2/25/10
to cfc...@googlegroups.com
Open the snippets view in either CFE or Builder
Create a new snippet
Add the snippet text, a name, and trigger text
in a CF document (builder and CFE snippets only work in Builder or CFE document types), type your trigger text and then cntrl-j or cmd-j depending on your system
View the awesomesauce that is the Snippet popup panel

J

Matt Quackenbush

unread,
Feb 25, 2010, 11:29:56 AM2/25/10
to cfc...@googlegroups.com

Nando .

unread,
Feb 25, 2010, 11:44:12 AM2/25/10
to cfc...@googlegroups.com
I've wandered a little far from the ColdFusion community in the last few years at times. You guys are incredibly helpful. Thanks again.

On Thu, Feb 25, 2010 at 5:29 PM, Matt Quackenbush <quack...@gmail.com> wrote:
http://trac.cfeclipse.org/wiki/CFSnippets

--
You received this message because you are subscribed to the Google Groups "CFCDev" group.
To post to this group, send email to cfc...@googlegroups.com.
To unsubscribe from this group, send email to cfcdev+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en.

Larry C. Lyons

unread,
Feb 25, 2010, 11:51:01 AM2/25/10
to cfc...@googlegroups.com
Its a real pity that CFBuilder doesn't work with a Snipex server. that
would be thoroughly awesome. For those who don't know, the Snipex
server is a small CF app that works very closely with CFEclipse to (of
course) server snippets.

--
Larry C. Lyons
web: http://www.lyonsmorris.com/lyons
LinkedIn: http://www.linkedin.com/in/larryclyons
--
The real problem is not whether machines think but whether men do.
- B. F. Skinner -

Sean Corfield

unread,
Mar 14, 2010, 6:08:23 AM3/14/10
to cfc...@googlegroups.com
Just catching up on some old threads because I've been crazy busy lately...

On Mon, Feb 15, 2010 at 6:44 AM, John Whish <john....@googlemail.com> wrote:
> Would you create and use a private getter and setter for mutating
> "foo"?

No. I avoid getters/setters as much as possible since they essentially
break encapsulation and I never use private getters/setters at all - I
see no point.

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html

Yes, there are times where you need to just 'get' data in order to
merge objects into procedural code (such as views) - but there are
other ways to do that too - so if you can avoid getters and setters,
your code will do less of this:

something = obj.getFoo() + obj.getBar();
obj.setFooBar( something );

That's horribly non-OO since you're performing the operation outside
the object rather than inside it.

*dons flame-retardant suit*
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies US -- http://getrailo.com/
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Kevin Pepperman

unread,
Mar 14, 2010, 6:39:41 AM3/14/10
to cfc...@googlegroups.com
Thanks for the link Sean-- that was a good read.
I especially like the last part of the article.

Getter/setter methods often make their way in code because the coder was thinking procedurally. The best way to break out of that procedural mindset is to think in terms of a conversation between objects that have well-defined responsibilities. 

I am amazed at how much "psudo OO" code I have been seeing lately, it seems like the rush to learn OO has many coders putting procedural code in components and passing data and objects around like candy.
I was always off-put by using getters in my view, or anywhere for that matter, I developed a habit of referencing the attributes/variables structures with the event/myFusebox beans in my objects with FB5 and I always was happy with the results. It always made more sense than calling a getter on a bean from the dark corners of my apps.

--
/Kevin Pepperman

"They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety." - Benjamin Franklin

denstar

unread,
Mar 14, 2010, 8:40:18 AM3/14/10
to cfc...@googlegroups.com
On Sun, Mar 14, 2010 at 3:08 AM, Sean Corfield wrote:
> Just catching up on some old threads because I've been crazy busy lately...
>
> On Mon, Feb 15, 2010 at 6:44 AM, John Whish wrote:
>> Would you create and use a private getter and setter for mutating
>> "foo"?
>
> No. I avoid getters/setters as much as possible since they essentially
> break encapsulation and I never use private getters/setters at all - I
> see no point.
...
>
> *dons flame-retardant suit*

So busy, and yet you're out trolling? ;)

I think that this is one of those deals where sweeping generalizations
don't really work, so I'll go ahead and bite.

I'd say a [g|s]etter could help with encapsulation, like say for with
a DAO who's data field names change a lot (first_name, firstName,
fname...).

Could help an IDE that wasn't all hip to javadoc-type stuff, too.

Are you just *etting strings and such, or "objects" and what have you?
What about AOP type stuff? Maybe that fine grained detail will come
in handy...

And really, one reason I'm working on CFE, is that a decent IDE, can
make a lot of this crap a mute (er, moot!) point: Click, click, boom!

:DeN

--
A whole army, though they can neither write nor read, are not afraid
of a platform, which they know is but earth or stone; nor of a cannon,
which, without a hand to give fire to it, is but cold iron; therefore
a whole army is afraid of one man.
James Harrington

Sean Corfield

unread,
Mar 21, 2010, 2:49:50 PM3/21/10
to cfc...@googlegroups.com
On Sun, Mar 14, 2010 at 5:40 AM, denstar <vallia...@gmail.com> wrote:
> I'd say a [g|s]etter could help with encapsulation, like say for with
> a DAO who's data field names change a lot (first_name, firstName,
> fname...).

Straw man. The DAO should map the column name to the business object
attribute. Nothing to do with get/set on a bean.

And there are situations - at the boundary between the OO model and
the procedural rendering code - where *some* getters are necessary
(unless you have a rendering method on your object and pass it a
parameterized string to perform replacements on - or some such).

The trouble is, if people start out from the position of
"encapsulation = add get/set for every property", they've already
completely broken encapsulation. If instead they start out from the
position of no get/set methods and only add them as external usage
seems to require them, they'll think more carefully about why they're
exposing the data.

denstar

unread,
Mar 21, 2010, 5:18:25 PM3/21/10
to cfc...@googlegroups.com
On Sun, Mar 21, 2010 at 12:49 PM, Sean Corfield wrote:

> On Sun, Mar 14, 2010 at 5:40 AM, denstar wrote:
>> I'd say a [g|s]etter could help with encapsulation, like say for with
>> a DAO who's data field names change a lot (first_name, firstName,
>> fname...).
>
> Straw man. The DAO should map the column name to the business object
> attribute. Nothing to do with get/set on a bean.

Hey, DAs are Objects too! ;)

I'm not really arguing that everything should have [s|g]etters, just
that it is a way to "encapsulate change". Although "encapsulating
change" is a loaded term...

> And there are situations - at the boundary between the OO model and
> the procedural rendering code - where *some* getters are necessary
> (unless you have a rendering method on your object and pass it a
> parameterized string to perform replacements on - or some such).

So foo.blah (get or set-- hey, how do we know? By looking at context?
== vs = ?) is "better" than foo.getBlah(), 90% of the time? Or
foo.blahAndBar = heh, is better than foo.setBlahAndBar(heh)? Or
should we just have "return this" vs. anything at all? :)

http://www.pragprog.com/articles/tell-dont-ask says basically the same
thing as the [g|s]etters are bad deal does, but avoids the above line
of reasoning.

I'm not advocating to blindly add [g|s]etters, and I'm also not
advocating to blindly remove [g|s]etters. I'm just advocating the
same thing you are, really-- think about what you're doing.

But /don't think too much/!

Doing mental acrobatics is swell for solving the problem, but if
you're doing them just to try to follow "general" advice (I spent two
hours on it, but now I don't have that setter/getter anymore! Does it
really matter? I don't know, I just heard it was a Good Thing...),
well... it's good practice but not very productive in the "get it out
the door" sense.

> The trouble is, if people start out from the position of
> "encapsulation = add get/set for every property", they've already
> completely broken encapsulation. If instead they start out from the
> position of no get/set methods and only add them as external usage
> seems to require them, they'll think more carefully about why they're
> exposing the data.

People should think carefully about how objects communicate, period.

There are lots of exercises that can help with this (whiteboards,
contracts, unit testing, etc.).

Change is a wily beast... "thar she blows!".

:DeN

--
Corpses are more fit to be thrown out than is dung.
Heraclitus

Sean Corfield

unread,
Mar 21, 2010, 8:09:21 PM3/21/10
to cfc...@googlegroups.com
On Sun, Mar 21, 2010 at 2:18 PM, denstar <vallia...@gmail.com> wrote:
> Hey, DAs are Objects too! ;)

DAOs are generally stateless singletons - so they don't have
attributes you might be tempted to expose via getters :)

> So foo.blah (get or set-- hey, how do we know? By looking at context?
> == vs = ?) is "better" than foo.getBlah(), 90% of the time?

No, I didn't say that.

Setting (or getting) raw data attributes on an object, by any means,
should be considered suspicious.

What I said was that there are procedural areas of code (such as
views) where readonly access to an object's attributes is useful,
pragmatically (although it can still be avoided via a render()-style
method).

> http://www.pragprog.com/articles/tell-dont-ask says basically the same
> thing as the [g|s]etters are bad deal does, but avoids the above line
> of reasoning.

Not sure what "above line of reasoning" you're referring to but it's a
good article and explains why you should tell your objects to do stuff
instead of asking them for their data (attributes) so that you can do
stuff with that data. Again, any use of setting (or getting) raw data
attributes on an object should be considered suspicious since it
violates the Tell, Don't Ask principle.

> I'm not advocating to blindly add [g|s]etters, and I'm also not
> advocating to blindly remove [g|s]etters.

Since my code starts with no get/set methods, I only have to worry
about adding them - very carefully, if the client code really needs
them. There's nothing to remove in my code :)

> Doing mental acrobatics is swell for solving the problem, but if
> you're doing them just to try to follow "general" advice (I spent two
> hours on it, but now I don't have that setter/getter anymore!  Does it
> really matter?  I don't know, I just heard it was a Good Thing...),
> well... it's good practice but not very productive in the "get it out
> the door" sense.

Ah, but the problem is you're trying to eliminate get/set and shift
from ask to tell rather than approaching a closed (encapsulated)
object and telling it to do something in the first place! If the
default is no get/set and a mindset of telling objects to do stuff
then you will occasionally make a deliberate shortcut of *adding* a
getter (and very rarely a setter) in order to "get it out the door" -
but that will be the unusual situation and a conscious choice to "do
the wrong thing" and you'll create a ticket to refactor it in the
future.

> People should think carefully about how objects communicate, period.

Yes. An exercise that I've found very valuable to help people 'get' OO
is to sit them down in a circle and give each person responsibility
for a single object. Then I ask them to get the job done by telling
each other to perform some action that is within that object's
capabilities. People seem to be much better at OO when you take them
away from code and make them interact like that - because in the real
world we don't generally ask for a bunch of data, perform some
calculation and then give the result back to the person we got the
data from...

denstar

unread,
Mar 22, 2010, 2:29:28 AM3/22/10
to cfc...@googlegroups.com
On Sun, Mar 21, 2010 at 6:09 PM, Sean Corfield wrote:

> On Sun, Mar 21, 2010 at 2:18 PM, denstar wrote:
>> Hey, DAs are Objects too! ;)
>
> DAOs are generally stateless singletons - so they don't have
> attributes you might be tempted to expose via getters :)

For them it's encapsulating the fields they access, right? Protecting
"the rest" from changes to underlying data structure?

They're all about encapsulating data access, right?

>> So foo.blah (get or set-- hey, how do we know? By looking at context?
>> == vs = ?) is "better" than foo.getBlah(), 90% of the time?
>
> No, I didn't say that.

I know. :)

/That/ was "the above line of reasoning"-- not what you said, but what
someone might take away from hearing "avoid getters and setters". :)p

...


> Not sure what "above line of reasoning" you're referring to but it's a
> good article and explains why you should tell your objects to do stuff
> instead of asking them for their data (attributes) so that you can do
> stuff with that data. Again, any use of setting (or getting) raw data
> attributes on an object should be considered suspicious since it
> violates the Tell, Don't Ask principle.

I love those pragmatic peeps! Excellent stuff!

Mostly that was my one point, such that it was-- "tell, don't ask" is
a lot more useful than saying "avoid getters and setters, especially
private ones".

And maybe that [g|s]etters are a valid pattern for encapsulating some
stuff, some times.

And to not have you having gone to the trouble of donning a flame-suit
for nothing.

>> I'm not advocating to blindly add [g|s]etters, and I'm also not
>> advocating to blindly remove [g|s]etters.
>
> Since my code starts with no get/set methods, I only have to worry
> about adding them - very carefully, if the client code really needs
> them. There's nothing to remove in my code :)

Damn you! How can I dispute this one... hrm... ah well. Obviously my
whole argument against your rule of thumb is pretty weak, so maybe I
could just call you names at this point?

Blaggard!

>> Doing mental acrobatics is swell for solving the problem, but if
>> you're doing them just to try to follow "general" advice (I spent two
>> hours on it, but now I don't have that setter/getter anymore!  Does it
>> really matter?  I don't know, I just heard it was a Good Thing...),
>> well... it's good practice but not very productive in the "get it out
>> the door" sense.
>
> Ah, but the problem is you're trying to eliminate get/set and shift
> from ask to tell rather than approaching a closed (encapsulated)
> object and telling it to do something in the first place! If the
> default is no get/set and a mindset of telling objects to do stuff
> then you will occasionally make a deliberate shortcut of *adding* a
> getter (and very rarely a setter) in order to "get it out the door" -
> but that will be the unusual situation and a conscious choice to "do
> the wrong thing" and you'll create a ticket to refactor it in the
> future.

Hey, I'm telling the thing to set it's first name! Maybe it's a
validator-type whatnot. heh.

And encapsulation is a multi-level, multi-pass (as you say) deal.

Take the svn tag I wrote. I could have done _intance.repository, but
I was pretty sure I'd need to do more than that, so I did
getRepository() at the outset.

Functions are a tired and true method of encapsulation (even if
they're ones that are procedural in nature).

Objects have procedure (or behavior, if you will), or else you'd never
be able to model flow and interaction.

There's probably always some kind of mix of procedure and action. Or
action and procedure, maybe.

Um, yeah.

Well, I'll stand by my previous assertion that an IDE with awesome
refactoring support makes a lot of this not as hard to change as it
otherwise might be. Which is part of why I'm working on CFE.

Scary, right? :)

:DeN

--
Eyes and ears are poor witnesses to people if they have uncultured souls.
Heraclitus

Sean Corfield

unread,
Mar 26, 2010, 8:43:04 PM3/26/10
to cfc...@googlegroups.com
On Sun, Mar 21, 2010 at 11:29 PM, denstar <vallia...@gmail.com> wrote:
> Blaggard!

I think you win a prize for being the first person to call me that on
a mailing list :)


--
Sean A Corfield -- (904) 302-SEAN

Railo Technologies, Inc. -- http://getrailo.com/

Reply all
Reply to author
Forward
0 new messages