What does "invariants" mean in this sentence "Public data is bad if a
class models an abstraction and must therefore maintain invariants" ??
An example is appreciated.
In addition to what others have said (which was all great
as far as I can see) an invariant is a condition that an
object must satisy to be valid. The invariant should be a
characteristic of the abstraction, or a property of the
implementation.
An invariant does not have to be true while an object
is actually performing one of its functions. As for
example, while an object is actually running its own
constructor, the invariant does not have to be true
until the ctor is finished and about to exit.
Consider a class that modeled a supersonic jet fighter/bomber
aircraft. One thing you might like to do in the spec of the
craft would be to prevent the accidental dropping of any
explosives while the plane is on the runway. So, you might
include a rule (very simple version follows):
- While the landing gear is extended, the weapons cannot
be fired or released.
- Attempts to do so will produce a warning indicator on
the pilot's information display.
So, the program that runs the aircraft will keep track of
the ability to use weapons or bombs. And it will keep track
of where the landing gear is. And it will keep the invariant
that when the landing gear is extended, the bombs and weapons
will not work. And it will also keep track of attempts to
fire the weapons, and tell the pilot why it does not work if
he tries to fire with the landing gear extended.
So, one invariant might be (in sloppy code form):
((extended landing gear) && (weapons can fire)) == false
At any time the code checks, it must be the case that
not both of extended landing gear and weapons can fire
are true. Note that the invariant does not have to be
true while the gear is actually being extended or
retracted. The code might extend the gear, killing time
somehow while it waits for the gear to move, then set
the "weapons can fire" flag to false, then return.
Another might be:
(extended landing gear) && (pilot tries to shoot) ==
(explanatory warning on display)
That is, whenever the gear is extended and the pilot tries
to shoot there must be a warning on the display. That way
the pilot will get a smackdown if he tries to shoot the
conning tower off the aircraft carrier.
Now, why would it be bad to let these data be public?
Suppose some other part of the code knew about the
"weapons can fire" flag. And suppose the pilot found
that by, for example, bouncing the gear up and down
or cycling the bomb bay door or something, he could
activate the weapons even with the gear extended.
That other function might set the "weapons can fire"
flag to true, even though the gear was still extended.
Bozo-the-pilot might wind up dropping his bombs while
he was sitting on the deck of an aircraft carrier.
This would be bad.
However, it is important to realize that any such situation
would be a bug in the code. In other words, making the data
private helps prevent bugs getting into the code by making
the maintenance coder unable to get at the stuff that might
break and screw things up.
Here is a much more mundane example: Cosider a code to
describe the wiring behind the walls in a house. An
invariant might be:
- Between one connection box to another, the wires are all
insulated and can't make connections.
If you let people get at the wires at any other place than
a connection box, then they can pull out their jack knife,
strip off some insulation, and solder in their desk lamp
at any old place. This is known as "how the fire started."
Keeping those electrical wires hidden in the walls helps
keep snoopy-britches from changing things.
Socks