Invariant:
A property of a program that is always true, for every possible runtime state of the program.
Most important property of a good abstract data type is that it preserves its own invariants. That means the ADT is responsible for ensuring that its own invariants hold, instead of depending on good behavior from its clients.
Such as:
Immutability
假想一种对客户有要求的String:
Contrast that with a string type that guarantees that it will be immutable only if its clients promise not to change it. Then you’d have to check all the places in the code where the string might be used.
representation exposure:
Code outside the class can modify the representation directly. It may threaten invariants and representation independence.
representation independence:
The use of an abstract type is independent of its representation.
representation(rep):
The actual data structure or data fields used to implement the class.
Rep invariants and abstraction function:
Consider the relationship between two spaces of values:
The space of representation values consists of the values of the actual implementation as a single object.
The space of abstract values consists of the values that the type is designed to support.
Commonly, a small network of objects is needed to implement the abstract values.
Two value spaces’ releationship
Note:
Every abstract value is mapped to by(由……映射而来) some rep value.
Some abstract values are mapped to by more than one rep value. There’s more than one way to represent an abstract value.
Not all rep values are mapped. Some reps may have no meaning.
Abstract Function
AF : R → A
The function is surjective/onto(满射的), not necessary injective/one-to-one(单射的), and therefore not necessarily bijective(双射的), and often partial.
Rep Invariant that maps Rep values to Booleans
RI : R → boolean
For a rep value, RI® is true if and only if r is mapped by AF, aks, the rep is well-formed/meaningful.
RI is the subset of rep values on which AF is defined.
RI(“”) = true, RI(“abc”) = true, and RI(“bac”) = true, but RI(“abbc”) = false.
Note: rep invariant is different from invariant.
Even with the same type for the rep value space and the same rep invariant, we might still interpret the rep differently.
In summary, there are five things to remember:
The abstract value space for the specification
The rep value space for the implementation
Deciding which rep values are legal, and the rep invariant is a function from rep values to boolean
Interpreting reps as abstract values
Writing these assumptions in your code
Checking the rep invariant
If your implementation asserts the RI at runtime, then you can catch bugs early.