The Artima Developer Community
Sponsored Link

Failure, Preconditions, and Reuse
A Conversation with Bertrand Meyer, Part IV
by Bill Venners
March 8, 2004

<<  Page 2 of 3  >>


Checking the Preconditions

Bill Venners: One of the recommendations you make in your book Object- Oriented Software Construction that has always surprised me is the notion that under no circumstances shall the body of a routine check for the precondition of the routine. I understand that you don't want to have the same condition being tested in multiple places, both the client and the supplier, as you called it, but you also said, "If the client's part of the contract is not fulfilled, that is to say if the class does not satisfy precondition, then the class is not bound by the post condition." So the supplier class can either throw an exception or return a wrong result. I tend to prefer defining exceptions that will be thrown if preconditions are broken, because then the behavior of the routine is specified even under broken preconditions. The behavior of the routine is fully specified. That's my intuitive preference. Could you describe your reasoning for recommending the other approach?

Bertrand Meyer: I don't think you're expressing a preference with respect to language rules, but rather, a preference for a design style that puts more responsibility on the supplier. That is to say, you prefer a design style in which the supplier in effect extends the specification to account for more cases. In the end, it's really a matter of design style. Personally, I have found it far more effective to define for each operation the conditions under which it will work, and leave the behavior undefined in other cases. I think in the end it's a more effective approach.

If you take the viewpoint of the client, what happens typically is this: You are writing some software and you instantiate a class. Assuming you are programming in a context in which the only way to use the class is through it's specification, which includes the contract, you'll see the pre-condition. If you are a reasonable client programmer, if you know what you are doing, you'll know to program against the precondition. Of course, you may not like the precondition. You may find it's too demanding, but that's life. It's part of the contract. I think that style works pretty well.

The other style is a bit more problematic. For example, I recently looked at some collections classes from .NET. You can see the interface for a certain library class, but you don't necessarily see the exceptions. If you're careful and serious, you will go deeper into the documentation of the class and see that some exceptions can be raised in certain cases. If you want to process such cases, you'll have to write a try catch structure in your own client code. That structure is actually more complicated than dealing with the negation of the precondition in the first place, because you're trying to do some task, and after the fact you have to catch possible violations and try to recover. So you will actually end up doing the same thing either way, but it's more complicated to deal with it after the fact than if you just checked the precondition in the first place. Likely, however, many programmers are simply not going to take the trouble to look at these exception clauses, or they might miss some of them. If something wrong happens, some exception will occur, and there's no guarantee at all whether and how the exception is going to be processed. Is it going to be processed properly? Is it going to be passed back up the call chain to a routine that has no clue about what actually happened? So it seems to me that this approach is really a way to ignore the problem, to put your head in the sand and pretend that nothing is going to happen, when in fact things can happen. It is better to tackle the problem head on, to have a specification that explicitly says what is expected of the caller to get correct treatment, and to make sure before the call that these conditions are satisfied.

<<  Page 2 of 3  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use