by nevdelap » Mon Jul 12, 2010 1:50 pm
Hi hopscc
Conditions that must be valid for the object to be in a valid state during execution are in the invariant, and can be in state invariants and loop invariants, and can be expressed as built in test as assertions in the body, which is executable test and documents the internals of the class - ie: is not part of the interface, is not of concern to the client, because if it fails it is a bug in the class.
If you want some internal state to be a precondition to executing a method it is simple - you have to expose it.
For example, if, for some reason, you have a stack with a limited size and you must only push onto a stack that is not full then you have to expose an isFull property and put in the preconditions not isFull (there are other possibilities that amount to the same thing). It can't just blow up, you can't expect the client to read your implementation, and you can't expect the client to read in the API doco don't push on a full stack and keep track of it themselves.
If the client cannot know what the precondition is then the precondition is not any type of precondition, not just not a DBC precondition, or not an Eiffel precondition.
It's simple - if an assertion in the body, an ensure, or an invariant fails it is the class's fault. If a precondition fails it is the callers fault. Is very clear cut. The finger is pointed where the responsibility lies.
There are plenty of references in Eiffel and in Microsoft Code Contracts on the web, and it is not just arbitrary Eiffel "contract's", it is a very coherent set of principles. Microsoft hasn't invented anything new here, even though they like to pretend they have. But it rocks that their weight is behind it now. It's also cool that Cobra's implementation is much better than Microsoft's "language agnostic" version - IMHO.
call me Nev.