From ruby-talk Mon Oct 21 16:59:32 2002 From: "Jason Voegele" Date: Mon, 21 Oct 2002 16:59:32 +0000 To: ruby-talk Subject: Re: Interfaces in Ruby X-MARC-Message: https://marc.info/?l=ruby-talk&m=103521959619828 Nat Pryce wrote: > On Sun, 2002-10-20 at 04:12, Jim Weirich wrote: >> On Fri, 2002-10-18 at 14:08, Nat Pryce wrote: >> >> > [...] Also, in my experience, DbC ends up polluting the class >> > interface with a lot of predicates, because it doesn't support the >> idea of protocols, [...] >> >> I'm not sure I understand the above comment. > > Often, when designing classes you define a protocol by which calls can > be made to the object. A simple example, a Socket object has methods to > connect, read and write data, shutdown the read or write stream, or > close both streams. You must call connect before calling read, write, > shutdown or close. Once you've called close, you cannot call read or > write again until you call connect again. Once you've shutdown the read > stream you cannot read, and similarly for write shutdown. [snip] > However, to specify this protocol in DbC you have to define > preconditions on whether the socket is open, and those preconditions > have to be defined in terms of public methods. [snip code example] > So you end up adding predicates to the public API of objects to track > the progress of the protocols used to interact with those object. Often > this also requires adding data members to keep track of the current > state of the object. This is all true, but consider what you must do when you don't use Design By Contract. Either you 1) check the constraints within each method (e.g. "defensive programming") or 2) you leave it up to clients to enforce consistency. Option number 2 obviously leaves a lot to be desired. Option number 1 suffers from the same drawbacks you mentioned for DBC, i.e. you still have to keep track of the state of the object to ensure consistency. In addition to these drawbacks, you lose all the things that DBC can provide for you: 1) Automatic checking of preconditions, postconditions, and invariants when run-time checking is enabled 2) Automatic and controlled inheritance of assertions 3) Automatic documentation of consistency constraints 4) Clear delineation of responsibilities 5) Reduced error-handling code I don't see what an ad-hoc solution can provide that outweighs these benefits. Basically, the way I see it, by not using DBC, you end up manually recreating a lot of it. > I found that when writing code that had a lot of composition, rather > than inheritance, contracts of classes would end up mirrored in the > interface of other classes that contained them, and in containers of > containers, and so on. If you changed the contract of a component > class, then the change would ripple through the containers. In very > compositional code, it became quite expensive to change contracts. Interesting point. Perhaps this is why Eiffel emphasizes inheritance so much more than any other language. -- Jason Voegele "We believe that we invent symbols. The truth is that they invent us." -- Gene Wolfe, The Book of the New Sun