Safe software needs to be not only correct (meet its
specification) but also robust (function sensibly in abnormal
situations). Formal methods are attacking the first
problem, but what of the second? Today's software is notoriously fragile:
stress it even slightly outside its design envelope, and, rather than
degrading (gracefully or otherwise), it shatters.
'Real' engineers get round this problem by over-engineering, building in
a safety factor, traditionally of
about 3. Software 'engineers' need something analogous: a technique for
making software robust in the face of unanticipated, unsafe, usage.
The sort of questions we need to ask (and possibly even to answer!)
include:
- What does it mean for software to be robust? How far can the
'over-engineering' analogy be taken, and where does it break down?
(Spotting where analogies break down is valuable; it shows where what
you are doing is essentially different, and hence interesting.)
- How can we fortify software? The object oriented
paradigm is interesting here, especially Bertrand
Meyer's ideas. One of his key contributions is
Eiffel's insistence on a
disciplined exception mechanism (rather than ad hoc mechanisms, like
Ada's, analogous to the 'goto'). Exception handling can make software
fault-tolerant -- an object can recover from an error -- or redundant --
a second object can leap into the breach when the first fails. And, how
can the failed component be restarted safely?
- How can robustness be measured? What sort of quality stamp can we put
on our objects to show how strong they are, and to show how much people
can depend on them if they choose to reuse them?
- How much does fortification degrade the object's performance under
ordinary conditions? How can this be minimized, and how much does the
minimization effort cost? How much performance degradation is
acceptable, given the increase in robustness?
- How does fortification impact on code clarity and understandability?
Does it clutter the code so much it becomes incomprehensible, or do we
just multiply inherit from RobustObject? How does it impact
modifiability and reuse?