Data structures should enforce access policies.
Classes should expose abstract interfaces to the essence of the data, without having to know its implementation
ex:
public interface Vehicle { double getPercentFuelRemaining(); }vs.
public interface Vehicle { double getFuelTankCapacityInGallons(); double getGallonsOfGasoline(); }In which case the former is better since it represents an abstract concept which we want rather than implementation details.
The worst option is to blithely add getters and setters.
Objects should hide their data behind abstractions and expose functions that operate on that data. Data structures should expose their data and have no meaningful functions.
Procedural code (using data structures) makes it easy to add new functions without changing the existing data structures. Object Oriented (using objects) on the other hand, makes it easy to add new classes without changing existing functions.
The opposite is also true
Procedural code makes it hard to add new data structures because all the functions must change. OO code makes it hard to add new functions because all the classes must change.
Law of Demeter: a module should not know about the innards of the objects it manipulates. An object should not expose its internal structure through accessors.
Avoid creating "Hybrid" structures - half object and half data structure (have some public variables but also functions).
Ex: The following are bad:
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath(); final String outputDir = ctxt.getAbsolutePathOfScratchDirectoryOption(); final String outputDir = ctxt.getScratchDirectoryOption().getAbsolutePath();
Instead, we should ask why/what is the purpuse of getting this path (for example to use as a file name for writing out to) and do that instead:
BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
bj 2019-09-22