Tool for inlining useless getter/setter call

P

Patrick May

Daniel Pitts said:
You're both right.

No, just me. ;-)
Accessors and mutators are useful for exposed "properties" of an
object.

There should be very few, if any, of those in most cases.
The tell, don't ask principle is a good one to follow in many cases,
but unfortunately it can greatly complicate simple task if taking to
an extreme. Imaging if you had to use a callback or listener to
calculate a sqrt: Math.calculateSqrt(new MySqrtListener()); Now,
MySqrtListener basically has to know the rest of the program (or
expose its results through an accessor. Oops, thats asking!

Calculating a square root is a reasonable example of telling
another object what to do. Saying:

double squareRoot = Math.sqrt(square);

is much preferable to:

Math.setSquare(square);
Math.sqrt();
double squareRoot = Math.getSquareRoot();

A profusion of accessors and mutators is definitely a code smell.

Regards,

Patrick
 
P

Patricia Shanahan

Jack wrote:
....
The thing is, HE define the specs, HE change them every week, so i just
can't make a good model/design and then implement it.
....

I am also working on a program whose specifications change rapidly and
unpredictably. It is a simulation program for my research. The best
result it can produce is something that makes me think of a new and
interesting question, but then I change the program to help me answer it.

My response is a mixture well documented interfaces and refactoring.
Invariants are *very* important, because they help limit the scope of
changes.

Patricia
 
M

Mark Space

Jack said:
Daniele:

it's the least of our problems. My boss don't care about anything execpt
testing for null everywhere. I didn't even know the word "JavaBean"
before i was hired.

I'm kinda confused how removing getters helps with checking for null.

How is:

if( object.getVaule() != null )

better than:

if( object.value != null )

I totally don't understand what's going to improve here.
 
S

Stefan Ram

Mark Space said:
How is:
if( object.getVaule() != null )
better than:
if( object.value != null )

The object-oriented notation would be

object.ifNullValue [ ... ];

, where »[ ... ]« indicates the block to be executed by »object«
if it deems itself to hold a »null value«. This is »Tell, Don't Ask.«

It can be expressed easily in Smalltalk this way.

In Java, one needs to write this like:

object.ifNullValue( new java.lang.Runnable(){ public void run(){ ... }}

See also

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox_p.html
http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox_p.html
http://www.purl.org/stefan_ram/pub/smalltalk-blocks-in-java
 
L

Lew

Stefan said:
The object-oriented notation would be

object.ifNullValue [ ... ];

, where »[ ... ]« indicates the block to be executed by »object«
if it deems itself to hold a »null value«. This is »Tell, Don't Ask.«

It can be expressed easily in Smalltalk this way.

In Java, one needs to write this like:

object.ifNullValue( new java.lang.Runnable(){ public void run(){ ... }}

Huh?

That's not inherent in an object-oriented approach, and distinctly
non-idiomatic for Java.

Also, in that particular expression the argument to 'ifNullValue()' is pretty
much guaranteed not to be null.

The normal Java approach is one of the two expressions Mark Space cited,
if( object.getValue() != null )
...
if( object.value != null )
(both of which would throw an NPE if 'object' were itself null).

This 'ifNullValue()' expression doesn't even have any useful meaning that I
can discern.
 
L

Lew

Patrick said:
No, it's a bad practice. Wherever possible, objects should be
immutable. Where not possible, follow the rule of "tell, don't ask."
If you have classes that poke around in the internals of other classes
in order to accomplish their goals, you need to repartition your
behaviors.

Widespread use of accessors and mutators is the sign of a poorly
designed system.

I completely disagree. Let the readers choose for themselves.

Your philosophy just threw out all JavaBeans, all bean property editors, all
IDEs, all of JPA, JSTL, JSF, in fact, just about every framework written for
Java. Quite frankly, I think calling accessors and mutators "sign of a
poorly designed system" is completely whacked. It is ingrained in Java
culture to use them.

I still aver that they are a best practice. They allow, for example, for the
actual attribute members to be private, for all kinds of checking and
invariant enforcement, control of exceptions, integration with and
proliferation of useful frameworks, and are manifestly responsible for the
great growth of all kinds of useful APIs. They add safety, enforce the
fundamental values of encapsulation and non-dependency, and author after
author touts them as best practices. I offer those facts in evidence.
 
D

Daniele Futtorovic

Patrick said:
No, it's a bad practice. Wherever possible, objects should be
immutable. Where not possible, follow the rule of "tell, don't ask."
If you have classes that poke around in the internals of other classes
in order to accomplish their goals, you need to repartition your
behaviors.

Widespread use of accessors and mutators is the sign of a poorly
designed system.

I completely disagree. Let the readers choose for themselves.

Your philosophy just threw out all JavaBeans, all bean property editors,
all IDEs, all of JPA, JSTL, JSF, in fact, just about every framework
written for Java. Quite frankly, I think calling accessors and mutators
"sign of a poorly designed system" is completely whacked. It is
ingrained in Java culture to use them.

I still aver that they are a best practice. They allow, for example,
for the actual attribute members to be private, for all kinds of
checking and invariant enforcement, control of exceptions, integration
with and proliferation of useful frameworks, and are manifestly
responsible for the great growth of all kinds of useful APIs. They add
safety, enforce the fundamental values of encapsulation and
non-dependency, and author after author touts them as best practices. I
offer those facts in evidence.


While I totally agree with you, I suppose he has some kind of a partial,
flawed point in cases, JavaBeans aside, where accessors and mutators
strictly and exhaustively transcend instance variables. Of course,
that's defying the purpose. Accessors and mutators should follow a
semantical pattern; they should reflect /what/ the Object is, /what/ it
does, in an abstract sense, rather than /how/ it is what it is and /how/
it does what it does (variable types are tale-telling enough for the
latter). This is especially crucial if one wishes one day to modify the
'how' or to extend the 'what'.
I find it quite astonishing there should be any controversy on this.
 
J

Jack

Mark Space a écrit :
I'm kinda confused how removing getters helps with checking for null.

How is:

if( object.getVaule() != null )

better than:

if( object.value != null )

I totally don't understand what's going to improve here.

I think you mixed 2 points, here :

1/ my boss : no "written" or checked invariant anywhere, but null everywhere
2/ me : in class defining accessors, don't use them in the class

For the ones asking why there is accessor, that's because we use them from the OUTSIDE of the class. My point is not to use them IN the defining class.
 
L

Lew

Jack said:
2/ me : in class defining accessors, don't use them in the class

For the ones asking why there is accessor, that's because we use them
from the OUTSIDE of the class. My point is not to use them IN the
defining class.

So don't.

Although many times there are excellent engineering reasons to use accessors
and mutators inside the same class, it is certainly not always. In cases
where you don't need to, don't do it.

Simple.
 
P

Patrick May

Lew said:
I completely disagree. Let the readers choose for themselves.

Your philosophy just threw out all JavaBeans, all bean property
editors, all IDEs, all of JPA, JSTL, JSF, in fact, just about every
framework written for Java.

Bean property editors, GUI builders, and DAOs are good examples
of exceptions to the rule, not because the rule is incorrect but
because the objects those tools are dealing with are closer to pure
data structures than to objects. Even for those tools, reflection now
provides a better alternative in many cases.

Object orientation focuses on behavior rather than data. Good OO
design does not gratuitously expose all data members via accessors and
mutators. Again, if you find that you have a need to access the state
of another object in order to implement a behavior in another object,
thats a good indication that you need to refactor your behaviors.
Quite frankly, I think calling accessors and mutators "sign of a
poorly designed system" is completely whacked. It is ingrained in
Java culture to use them.


Quite frankly, suggesting that a profusion of accessors and
mutators is good OO design is definitely "whacked." Inflating a class
interface that way increases coupling and decreases maintainability
and extensibility. It's simply bad design.

Whether or not it is ingrained in the Java culture (which I
dispute) is immaterial. Profusion of accessors and mutators is a
strong indication that you are doing procedural programming with a
thin OO veneer. There's nothing wrong with procedural programming per
se, but it won't give you the dependency management benefits of OO.
I still aver that they are a best practice. They allow, for example,
for the actual attribute members to be private, for all kinds of
checking and invariant enforcement,

They inflate the interface that must be supported moving forward
and couple the internal design to that interface, making it difficult
or impossible to change.
control of exceptions, integration with and proliferation of useful
frameworks, and are manifestly responsible for the great growth of
all kinds of useful APIs. They add safety, enforce the fundamental
values of encapsulation and non-dependency, and author after author
touts them as best practices. I offer those facts in evidence.

There are better ways to build OO systems. Rampant use of
accessors and mutators violates good OO design principles. Putting
them in as a matter of course is coding without thinking.

Sincerely,

Patrick
 
P

Patrick May

Daniele Futtorovic said:
While I totally agree with you, I suppose he has some kind of a
partial, flawed point in cases, JavaBeans aside, where accessors and
mutators strictly and exhaustively transcend instance variables. Of
course, that's defying the purpose. Accessors and mutators should
follow a semantical pattern; they should reflect /what/ the Object
is, /what/ it does, in an abstract sense, rather than /how/ it is
what it is and /how/ it does what it does (variable types are
tale-telling enough for the latter). This is especially crucial if
one wishes one day to modify the 'how' or to extend the 'what'.

I find it quite astonishing there should be any controversy on this.

So do I. You've just described exactly why indiscriminate use of
accessors and mutators is a bad idea. Inflating the interface
unnecessarily leads to maintenance and enhancement problems.

Objects should tell each other what to do, not ask each other for
state.

Regards,

Patrick
 
D

Daniel Pitts

Patrick said:
So do I. You've just described exactly why indiscriminate use of
accessors and mutators is a bad idea. Inflating the interface
unnecessarily leads to maintenance and enhancement problems.

Objects should tell each other what to do, not ask each other for
state.
Asking for state versus asking for properties are different (and often
confused) concepts.

foo.getQuery() could be thought of telling foo to tell me the query
property it owns.

Too many people can't separate state from properties in their class
design, and I think that's what you (Patrick) has been warning against.
To say that getters/setters are all bad is too broad. They are oft
abused for sure, same with null!
 
D

Daniele Futtorovic

So do I. You've just described exactly why indiscriminate use of
accessors and mutators is a bad idea. Inflating the interface
unnecessarily leads to maintenance and enhancement problems.

To restate the point, what I was saying is that it's a bad idea to
simply write an accessor (and possibly a mutator) for each and every
instance variable. Such indiscriminate use is indeed a bad idea. But I
didn't intend the statement to include other, possibly indiscriminate,
uses. IOW, it wasn't directed against the use of accessors and mutators
itself.
Objects should tell each other what to do, not ask each other for
state.

You seem to ignore the fact than an Object can purposefully be a holder
of a state. As such, its state would be its property. And as soon as
that state become in the slightest way dynamic, that Object will also be
a "doer". It amounts to the exact same thing whether you "tell" an
object to report its state to you or whether you "ask" it for its state.
As for the strictly imperative approach you could be interpreted as
advocating, it may be an interesting paradigm, but one thing is for sure
and that's that it hasn't its place in the Java language.

I didn't advocate against accessors and mutators, but against a very
specific /spirit/ in which they could be applied. I would still maintain
that, as a rule, a class should *never* expose instance variables. As a
valid exception to this rule, such a highly specific and "leafy" (in the
class tree) class as GridBagConstraints comes to mind.
Everything else which describes a property of the Object, regardless of
whether it is implemented via a single variable or not, should be
accessed through methods, not directly. It is true, as you say, that
this inflates the interface. I disagree that this is unnecessary. I
disagree that it leads to maintainance problems. I maintain that it is
_vital_ for enhancement.

The OP has later refined his question to uses of accessors and mutators
methods of an Object /within/ the Object's class. But even there these
methods make a great deal of sense: for polymorphism (I am, by the way,
strictly opposed to the "classes and variables should be final by
default" idiom). What's more, this kind of strict separation between the
code in a class and the one outside of it is wrong, IMO. The separation,
again, should be a semantical one. It's the design that matters here.
And as design goes, encapsulation is almost a categorical imperative
(there is of course no such thing as Cant's categorical imperative, but
almost). It is well appropriate to define different levels of
encapsulation within a class itself, levels which you can later extract
and put in their own class as the codebase grows. Again: ease of
maintainability. Considering code in a chorogically dynamic perspective,
there is no such thing as a strict boundary between classes.

df.
 
P

Patrick May

Daniele Futtorovic said:
To restate the point, what I was saying is that it's a bad idea to
simply write an accessor (and possibly a mutator) for each and every
instance variable. Such indiscriminate use is indeed a bad idea.

Excellent! That's exactly what I was saying as well.
But I didn't intend the statement to include other, possibly
indiscriminate, uses. IOW, it wasn't directed against the use of
accessors and mutators itself.

I'm not sure I follow this. If you're saying that access and
mutation of internal data members, when absolutely necessary, should
be via methods rather than exposing those data members publicly, that
makes perfect sense.
You seem to ignore the fact than an Object can purposefully be a
holder of a state.

I mentioned DAOs and similar data structures wrapped as objects
elsethread. While this technique is necessary in some areas of a
typical system, that level of exposure is inappropriate in
behavior-focused objects.
I didn't advocate against accessors and mutators, but against a very
specific /spirit/ in which they could be applied. I would still
maintain that, as a rule, a class should *never* expose instance
variables.

I agree, although no doubt someone will now come up with a
compelling exception to that rule.

Regards,

Patrick
 
P

Patricia Shanahan

Daniele Futtorovic wrote:
....
To restate the point, what I was saying is that it's a bad idea to
simply write an accessor (and possibly a mutator) for each and every
instance variable. ...

Taking this a stage further, I don't think an accessor need necessarily
be directly associated with an instance variable.

In my mind, a getter or setter is related to a logical attribute of the
object. That attribute may or may not be represented by an instance
variable. It may be something the object can calculate and/or control in
some other way.

Patricia
 
D

Daniel Pitts

Patricia said:
Daniele Futtorovic wrote:
....

Taking this a stage further, I don't think an accessor need necessarily
be directly associated with an instance variable.

In my mind, a getter or setter is related to a logical attribute of the
object. That attribute may or may not be represented by an instance
variable. It may be something the object can calculate and/or control in
some other way.

Patricia
It may even be a property that is represented by a composite of fields,
or a property derived from some other field's properties.
 
P

Patricia Shanahan

Daniel said:
It may even be a property that is represented by a composite of fields,
or a property derived from some other field's properties.

and that, I think is important to the question of whether code inside
the class should use the getter or setter. If it is using or controlling
the logical attribute, it should do so through the getter or setter.

That way, the only code that has to change if the implementation of the
attribute changes is the code that represents the implementation. Code
that uses the attribute does not care whether it is represented by a
simple variable, or calculated in some other way.

Patricia
 
P

Patricia Shanahan

Jack said:
Mark Space a écrit :



I think you mixed 2 points, here :

1/ my boss : no "written" or checked invariant anywhere, but null
everywhere
2/ me : in class defining accessors, don't use them in the class

For the ones asking why there is accessor, that's because we use them
from the OUTSIDE of the class. My point is not to use them IN the
defining class.

However, I think there is an indirect relationship. The more your code
is subject to unpredictable changes, the stronger the motivation for
keeping it as flexible as possible.

Suppose some later, boss-imposed change forces you to replace the
variable with a calculated value. If you access it directly inside the
class, you need to change all code in the class that uses the logical
attribute. If you only access the variable directly in code that really
needs to use the variable, not the attribute, you will have the minimum
possible amount of code to change.

Patricia
 
J

Jack

Patricia Shanahan a écrit :
However, I think there is an indirect relationship. The more your code
is subject to unpredictable changes, the stronger the motivation for
keeping it as flexible as possible.

That's exactly what he thinks too. To him, flexible means : test everything, no invariant, no pre/post conditions, ...

One day, he even said : "returning null enable us to report to a superior level the error". I think that's what exceptions are done for, but he just don't want to change his point of view.

Suppose some later, boss-imposed change forces you to replace the
variable with a calculated value. If you access it directly inside the
class, you need to change all code in the class that uses the logical
attribute. If you only access the variable directly in code that really
needs to use the variable, not the attribute, you will have the minimum
possible amount of code to change.

That's true in theory, but in 3 years it has never happend to us. So i think it doesn't worth it.


So the conclusion is that i will inline some getters/setters call one by one (with eclipse)... only for the cases where the fields behind the getters/setters are unlikely to change ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top