[… socket example elided …]
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 a good example and you raise a good point. Classes that make
their clients overly aware of their internal state is bad coupling for
several reasons, and this adds another reason to that list.
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. I’ve not noticed this effect in my own code. I generally
think of objects that use composition as a firewall against changes. If
an internal object changes its behavior, then the composing object
should compensate to provide consistent behavior to the client. Of
course, these are general statements and not always possible, so your
point is a valid one.
Hmmm… I wonder if it would be feasible to create a deferred class that
contained the contract. Then the composing class could inherit the
contract and changes to the contract could be automatically propagated.
Thanks for your insights.
···
On Mon, 2002-10-21 at 11:12, Nat Pryce wrote:
–
– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich
“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)