Java Reference
In-Depth Information
Some additional features should be included in the class, such as accessors for the
field values, but these are left as exercises.
Invariants bring to light the importance of proper encapsulation. If the TimeSpan
class weren't encapsulated, we would not be able to properly enforce our invariant. A
buggy or malicious client would be able to make a TimeSpan object's state invalid by
setting its fields' values directly. When the class is encapsulated, it has much better
control over how clients can use its objects, making it impossible for a misguided
client program to violate the class invariant.
Changing Internal Implementations
Another important benefit of encapsulation is that it allows us to make internal
design changes to a class without affecting its clients. A subtlety of classes is that the
internal representation of a class does not necessarily have to match the external view
that the client sees. A client of the TimeSpan class thinks of each time span as a num-
ber of hours and a number of minutes. But the TimeSpan object does not have to
internally store its time using those two data fields. In fact, the code for TimeSpan
becomes simpler if we simply store a single field for the total number of minutes. For
example, we can represent 2 hours and 15 minutes as 135 total minutes by converting
each hour into 60 minutes.
Let's rewrite the TimeSpan class to use only a single total minutes field:
// alternate implementation using only total minutes
public class TimeSpan {
private int totalMinutes;
...
}
Because our class is encapsulated, as long as our methods still produce the same
results from an external point of view, we can change the implementation of the
object's internal state and the clients will not need to be modified. We can imple-
ment the same constructor, add , and toString behavior using total minutes. For
example, the add method needs to combine the hours and minutes together and
add both of them into the totalMinutes . We'll scale the hours by 60 as we add
them to the total:
public void add(int hours, int minutes) {
if (hours < 0 || minutes < 0) {
throw new IllegalArgumentException();
}
totalMinutes += 60 * hours + minutes;
}
Notice that this new implementation makes it easier to enforce our class invariant
about objects having valid state. We must still check for negative parameters, but we
 
Search WWH ::




Custom Search