A genuine exception to a fundamental OOD rule?
Scenario:
You have a small class which is package access and has no meaning outside of the context of the application under development - i.e., it is impossible to imagine a scenario in which you would want to reuse it. The class is going to be involved in extremely processor intensive work. It has a member int value and a straight-up getter for this value is indispensible under the circumstances.
Is it a good idea to NOT encapsulate this value? You can rely upon your own good sense to keep you from setting the value directly. There is method call overhead to be saved...
I am actually faced with this situation right now.
Drake
[665 byte] By [
Drake_Duna] at [2007-10-2 11:06:43]

Well, first I'd do some testing to see if the method call overhead really makes a significant difference in the context in which it's being used. That is, what you do with that value after getting it would have to be very minimal for a method call overhead to matter.
But if you determine that there is in fact a meaninful performance gain to be had, then sure, go ahead. Package scope is really not much different from private. Just document why you're doing it.
> Well, first I'd do some testing to see if the method
> call overhead really makes a significant difference
> in the context in which it's being used. That is,
> what you do with that value after getting it would
> have to be very minimal for a method call overhead to
> matter.
Note that the theory (but that's only theory) would assume that there will be no difference, using Hotspot : Hotspot should be able to determine that the method is not overridden by any subclass, hence replace a virtual call for a final call. If the method is called that much, it will probably be inlined on the fly as well, so the result in the native code generated will be the same as a field access.
That's only theory, but if you want to know practically, then as jverd says, bench it, and don't try to optimize this accessor if this doesn't deserve it.
> It has a member int value and a straight-up getter for this
> value is indispensible under the circumstances.
>
> Is it a good idea to NOT encapsulate this value?
A getter might give a fuzzy warm feeling but it doesn't provide any significant functionality (at least as long as your design is reasonably well done.)
Other than that the two statements above seem contradictory. The first says that you need the getter. The second says you want to get rid of it.
And of course finally you should not guess as to what will impact performance - you should instead actually measure it. And you measure the application, not a method.
> Scenario:
>
> You have a small class which is package access and
> has no meaning outside of the context of the
> application under development - i.e., it is
> impossible to imagine a scenario in which you would
> want to reuse it. The class is going to be involved
> in extremely processor intensive work. It has a
> member int value and a straight-up getter for this
> value is indispensible under the circumstances.
>
> Is it a good idea to NOT encapsulate this value? You
> can rely upon your own good sense to keep you from
> setting the value directly. There is method call
> overhead to be saved...
>
> I am actually faced with this situation right now.
>
> Drake
my 2c :
Dimension is public and HEAVILY reused, and was designed to expose 'x' and 'y' attribute members as public for performance reasons (or so I read)
I would be HEAVILY reluctant to do such a thing anyway ;-)
> Other than that the two statements above seem
> contradictory. The first says that you need the
> getter. The second says you want to get rid of it.
Sorry, that was phrased badly. What I meant was that it was necessary to be able to simple get the value (whether directly or by way of a getter) without performing any other operations first. Actually the project has gone away anyway, but what I take away from this is, once again, avoid optimization when possible, and when not, test first.
Drake
Drake, why not simply make the object immutable then?
final class Smeagol {
final public int value;
protected Smeagol() {
super();
this.value = value;
}
}
I agree that *many* data objects (such as DTO's or VO's or most JavaBeans) could easily instead be the Java equivalent of a 'struct', all members public (and potentially final). If you have a variable with both a getter and a setter and no behavior or business logic, why not simply leave it as a public variable?
I think the problem is that in constrained situations, the above is fine. Programmers, however, might be tempted to take inappropriate short-cuts using the above, leading to problems. So, a blanket rule is offerred up. Expert programmers also are 'required' to encapsulate what is in fact a struct and provide accessors and mutators. This slight 'cost' is usually more than paid-by having less experienced developers avoid the use of non-encapsulated variables.
- Saish
Sorry, that ctor should take an int.
public Smeagol(final int value) {
super()
this.value = value;
}
- Saish
>
> I think the problem is that in constrained
> situations, the above is fine. Programmers, however,
> might be tempted to take inappropriate short-cuts
> using the above, leading to problems. So, a blanket
> rule is offerred up. Expert programmers also are
> 'required' to encapsulate what is in fact a struct
> and provide accessors and mutators. This slight
> 'cost' is usually more than paid-by having less
> experienced developers avoid the use of
> non-encapsulated variables.
In my experience the reason is usually because it is 'better'. When challenged the statement is made that it is 'more' OO or 'more' encapsulated.
The only time usage is a problem is when there is a design problem. And design problems would show up regardless of the exposure methodology used (since they are both basically the same.)
Additionally my experience has been that using methods is more likely to lead to hacks around a problem rather than the more correct solution of refactoring because the design is wrong (either because it always was wrong or because it is no longer correct.)
Even so I tend to prefer methods these days simply because they tend to lend certain convienence and because I have given up on actually working anywhere where rigorous process control would prevent a hacking mentality (so I might as well make it easier for the future hack.)
> Is it a good idea to NOT encapsulate this value? You
> can rely upon your own good sense to keep you from
> setting the value directly. There is method call
> overhead to be saved...
One question: Do you need to set this value after intially creating the Object it resides in? If not, make it final.
More an more I have been using packages as my main level of abstraction. If you are operating under this model, making getters for your package level Object members is as meaningful as making getters for your private variables. There are reasons to do it but it's not something you need to everytime.
It's kind of like creating a private inner class. Should you create getters and setters? You can't prevent access to the private members of the inner class so what does it buy you?
> In my experience the reason is usually because it is
> 'better'. When challenged the statement is made that
> it is 'more' OO or 'more' encapsulated.
>
Fair enough. Though a 'pure' DTO with no validations or dependencies between fields could easily be the Java equivalent of a struct as well. No?
> The only time usage is a problem is when there is a
> design problem. And design problems would show up
> regardless of the exposure methodology used (since
> they are both basically the same.)
>
Definitely agree.
> Additionally my experience has been that using
> methods is more likely to lead to hacks around a
> problem rather than the more correct solution of
> refactoring because the design is wrong (either
> because it always was wrong or because it is no
> longer correct.)
>
Hmm... not sure what you were trying to get at there JSchell. Are you saying, all things being equal, other developers are more likely to hack an encapsulated object (with mutators and accessors) than a Java struct contruct?
> Even so I tend to prefer methods these days simply
> because they tend to lend certain convienence and
> because I have given up on actually working anywhere
> where rigorous process control would prevent a
> hacking mentality (so I might as well make it easier
> for the future hack.)
Sadly, I do as well. That's why I indicated above 'only in certain constrained situations'. These do not materialize day to day for me on a regular basis.
- Saish
> > In my experience the reason is usually because it is
> > 'better'. When challenged the statement is made that
> > it is 'more' OO or 'more' encapsulated.
> >
>
> Fair enough. Though a 'pure' DTO with no validations
> or dependencies between fields could easily be the
> Java equivalent of a struct as well. No?
Of course. That is how I implement DTOs in C++. But I wanted to address what I thought was the suggestion that getters were used by experienced programmers while public attributes weren't. (But that might not have been what you meant.)
>
> > Additionally my experience has been that using
> > methods is more likely to lead to hacks around a
> > problem rather than the more correct solution of
> > refactoring because the design is wrong (either
> > because it always was wrong or because it is no
> > longer correct.)
> >
>
> Hmm... not sure what you were trying to get at there
> JSchell. Are you saying, all things being equal,
> other developers are more likely to hack an
> encapsulated object (with mutators and accessors)
> than a Java struct contruct?
>
They are more likely to hack with getter/setters than with public attributes.
The reason being that they can just change the getter/setter of course rather than spending time to actually figure out why the attribute is being used in the first place.
> Of course. That is how I implement DTOs in C++. But
> I wanted to address what I thought was the suggestion
> that getters were used by experienced programmers
> while public attributes weren't. (But that might not
> have been what you meant.)
>
Okay. Actually, what I meant was the following:
> Inexperienced developers should be 'forced' to use mutators/ctors and accessors, providing encapsulation. This is because judgement for when violating encapsulation should be left to more experienced developers. The potential harm from routinely breaking encapsulation by inexperienced developers is, IMO, the 'justification' for requiring encapsulation versus direct field access
> Experienced developers, on the other hand, may be able to discern when encapsulation can be violated. Generally, encapsulation is a good thing, though as I think we both agree, it should not be a straightjacket.
> They are more likely to hack with getter/setters than
> with public attributes.
>
> The reason being that they can just change the
> getter/setter of course rather than spending time to
> actually figure out why the attribute is being used
> in the first place.
Interesting. Never thought about it that way. Though, as I start to mentor more and more, I may have a moment of future irony when a junior developer does just that. :^)
- Saish
