|
Re: Design by Contract
|
Posted: Dec 10, 2003 10:52 AM
|
|
One little additional remark about pre- and post- conditions. Bertrand Meyers mentioned the possibility of calling boolean functions from within condition checking code in the context of graph algorithms. The mere fact of being able to theoretically invoke some function to check a condition is not sufficient to make the use of pre-conditions usable.
The big question behing usability is also complexity. If the checking condition has a bigger computational complexity (in the information theoretical sense) that the routine it is supposed to check, then it is practically unsable. A famous example was known in C++ some years ago, with the Rogue Wave Tools.h++ library, who had post-condition checks in debug mode in every significant method, so in that sense it fully implemented the pre- and post-condition policy advocated by M. Meyer. The library offered the notion of a sorted container and the insertion operation post-condition implemented just what Bertrand Meyer mentioned in the article, that is the check that all previous elements were still there in the same relative order. The only problem is that the insertion routine had a linear complexity, whilst the post-condition check was quadratic. The net effect was that we could not use the debug version of the library on this particular container and had to turn off the debug mode explicitly, because turning to debug mode was unacceptybly slow when a lot of elements was involved.
Even more seriously, in the domain of graph theory, most intersting pre- and post-conditions are simply not testable at all, mainly for complexity reasons. There may be for example no better checking algorithm than one with n-p complete complexity. If I say for example that the pre-condition is that my graph should have a Hamiltonian cycle, then I simply just can't check it in a reasonable amount of time, although the service offered by my method could be very simple. Even in the case where I would be ready to take the additional running time complexity into account, it is probably still not usable, because debugging the checking routine would be way much more complex than the simple service I'm attempting to check in the first place.
I'm personnally totally convinced of the effectiveness of pre- and post- conditions in the drastic reduction of debugging effort, and I use it consistently since many years and it really pays off. I'm just attempting to emphasize that it is not always applicable in practice. Most of the time, the pre- and post- conditions are simple enough to be easily implemented and the little extra effort is worth the trouble. But sometimes, you just can't use it. It's not a panacea.
|
|