Indirect Access

You can hide accesses and changes to state behind method invocations. These accessor methods provide flexibility at the cost of clarity and directness. Clients no longer assume that a certain value is stored directly. Thus, you are able to change your mind about storage decisions without affecting client code.

My default strategy for accessing state is to allow direct access inside of a class (including inner classes) and indirect access for clients. This strategy has the advantage that it allows clear, direct access to state for most accesses. Note: if most accesses to an object’s state are outside the object, there is a deeper design problem lurking.

Another strategy is to use indirect access exclusively. I find this results in a loss of clarity. Most getting and setting methods are trivial. They often outnumber methods that perform useful work, making the code hard to read. All those getting and setting methods are mighty tempting too. Rather than figure out where a calculation belongs, it is often expedient to implement it wherever and use the accessor methods to deliver the necessary state to make it work.

One definite case for indirect access is where two pieces of data are coupled. Sometimes this coupling is very direct, as in a cached value:

Rectangle void setWidth(int width) {
this.width = width;
area = width * height;
}

Other times the coupling is less direct, through a listener:

Widget void setBorder(int width) {
this.width = width;
notifyListeners();
}

Such coupling is unattractive (it is easy to forget to maintain the implied constraints) but may be the best available option. In such a case, indirect access is best.

Implementation Patterns

contents