Object-orientation and type checking protect from certain type of errors, but they don't impose specific behavior on class methods.
Runtime assertions and to a lesser extent unit-tests guard invariants.
Unit-tests ensure (or, rather, try hard to disprove) the fact that in certain predictable cases the software behaves exactly as predicted.
There are also design-by-contract frameworks (like Class::Contract) that do all of the above, however at a performance cost, plus it's a bit of take it or leave it. One cannot say "ok, we had a bug yesterday, so I'm adding a contract wrapper to this sub so we can avoid it in the future".
All different, each serves its own purpose...
|