Tim said:
They violate encapsulation, reduce maintainability, and in most cases
indicate a designer that didn't understand the problem domain. An
excellent article on their problems is here:
Allen Holub hit on some good points and got overly zealous. Return
interfaces when possible, yes. Strive to have classes do work that is
properly their responsibility, yes. Strive not to have unnecessary
accessors, yes.
I can't take his page 2 example (getX() returning long instead of int) too
seriously. I'm sorry, but if you don't have enough of a handle on your
problem to figure out what primitive types you need to use, you're likely
also having problems deciding how to design your classes. The decision as
to what integer type or floating point type to use should get as much
attention as your class design.
As far as encapsulation goes, a better term to use is "information hiding"
(see Wikipedia). Given that latter phrase, using getters & setters is only
problematic insofar as it ties one to implementation. To allude to
http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html (a
link in the Wiki article on information hiding), let's assume we have a
Position class that describes a position in 3D space. Now, internally this
may be stored as 3 doubles for x, y and z, or a 3-element array of doubles,
or in spherical coordinates (radius, zenith angle, azimuth angle, all in
double). Now, for calculations involving two or more Positions (like
distance) ideally you'd have methods that work with Positions, not the
specific coordinates. But for a situation where another class may actually
need the coordinates, and you supply getX(), getY() and getZ(), and
possibly even corresponding setters, this is *not* violating information
hiding, for several reasons. One, (z,y,z) has real physical meaning in the
problem domain. Two, just because you are returning (or setting) x,y and z
doesn't mean that the internal storage is 3 doubles.
Maintainability? Non-issue. Getters & setters should be for visible
attributes of the class. In the above example x, y and z are indisputably
visible (real) attributes of a 3D position. Provided that the getX/setX etc
accessors are properly translating between (z,y,z) and the actual
implementation (something only done in one class), any client class can
very easily work with (x,y,z). Provided that you follow this principle you
ought not to have problems with accessors.
AHS