[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Re: Interfaces in Ruby
From:       "Jason Voegele" <jason () jvoegele ! com>
Date:       2002-10-21 16:59:32
[Download RAW message or body]

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



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic