Examples
Example 1: Proper encapsulation.
Most classes (e.g., Matrix, File, Date, BankAccount, Security) should have all private data members and expose adequate interfaces. Allowing calling code to manipulate their internals directly would directly work against the abstraction they provide and the invariants they must sustain.
A Node aggregate, as commonly used in the implementation of a List class, typically contains some data and two pointers to Node:next_ and prev_.Node 's members don't need to be hidden from List. But now consider Example 3.
Example 2: treeNode.
Consider a TRee<T> container implemented in terms of treeNode<T>, an aggregate used within TRee that holds previous//pointers and a T object payload. treeNode's members can all be public because they don't need to be hidden from TRee, which directly manipulates them. But tree should hide treeNode altogether (e.g., as a private nested class, or defined only in tree's implementation file), because it is an internal detail of tree that callers shouldn't depend on or manipulate. Finally, TRee does not hide the contained T objects, because the payload is the caller's responsibility; containers use the iterator abstraction to expose the contained objects while hiding internal structures.
Example 3: Getters and setters.
If there is no better domain abstraction available, public and protected data members (e.g., color) can at least be made private and hidden behind get and set functions (e.g., GetColor, SetColor); these provide a minimal abstraction and robust versioning.
Using functions raises the level of discourse about "color" from that of a concrete state to that of an abstract state that we are free to implement as we want: We can change to an internal color encoding other than int, add code to update the display when changing color, add instrumentation, and make many other changes without breaking calling code. At worst, callers just recompile (i.e., we preserve source-level compatibility); at best, they don't have to recompile or relink at all (if the change also preserves binary compatibility). Neither source nor binary compatibility is possible for such changes if the starting design has a public color member variable to which calling code becomes tightly coupled.
 |