Java Encapsulation – Should a Class Provide Public Mutators for Private Fields?

encapsulationgettersjava

I work on refactoring an Java application based on a CAST audit. One of the criterion says that

To respect OO encapsulation concepts, private fields should always be
accessed through accessors

So far, so good. However, the audit highlights all private fields in the class that have no mutators, regardless how they are being used.

In my case, these fields are only accessed from inside the class.

I could provide private accessors for all of them, but for readability purposes, I do not think it is a good idea. Furthermore, I do not see how providing private getters for private attributes enhances OO encapsulation.

I could also provide public mutators for all fields. I have seen it done in many applications. Come to think of it, most IDEs provide a functionnality that automatically generates public mutators for all of the class attributes…

But I wonder, is it not against the very principle of encapsulation to provide public accessors for private attributes that are only meant to be used inside the class?

EDIT : my question is not about the use of accessors inside their own class. It is about the relevance of providing public accessors for all private fields in the class, regardless they are used outside the class or not.

Best Answer

While there are few hard and fast rules in software design and development, there's a school of thought that mutators/getters/setters for every attribute of a class are an anti-pattern or at least not a good practice for OOP.

At least in some measure, the widespread use of getters/setters seems to have been heavily influenced by JavaBeans, which are not particularly object oriented, or at least not a general case of object orientation. Some people went as far as to claim that getters/setters were "evil" (in 2003!) or "considered harmful".

I wouldn't go as far, but I do think many getters/setters tend to weaken or sidestep guidelines such as Tell, Don't Ask and encapsulation. If an attribute is an implementation detail, an internal of the class, why should it be exposed through its interface?

Getter/setters are in some cases also a historical "artifact" of some persistence frameworks that used to require them (or at least encourage their use) to persist/load objects to and from the datastore. In that case, a technical detail ended up encouraging bad OO design.

With all this in mind, I think one thing can be said: no, a class should NOT provide public mutators for all its private fields. It might be necessary in some cases, but as a general principle it's not correct.