Long Chain Cyclic Dependence

Please present an example of fixing long-chain cyclic dependence with MultipleInheritance. This reader would also appreciate a definition of "long-chain cyclic dependence".

I might further note that I can't remember ever wanting MultipleInheritance, nor have I recently come out against it. I do not own stock in any SingleInheritance companies except ObjectShare.. --RonJeffries

A typical smalltalk programmer's response :-)

Okay, first definitions. Class B is dependent on class A IfAndOnlyIf compile-time knowledge of the interface to class B requires compile-time knowledge of the interface to class A. What's significant about this is that a requirement to change the interface of class A has the potential to require a change to the interface of class B.

A cyclic dependence occurs when class A and class B depend on each other. 1-to-1 cycles are unavoidable - nodes and links in a graph, or one of many varieties of parameterizing on types ... there are lots of cases where you can't do without this.

But there's potential for real maintenance trouble when the cycle involves > 2 classes. The trouble comes when changing the interface to A requires changing the interface to B which requires changing the interface to C ... which requires changing the interface to A again. Involve several other classes in this unholy cycle and you've got a small change request exploding into an unpredictable amount of work. Involve several other cycles and ... game over, man.

So you can use MultipleInheritance to break such a cycle this way: if we have (pardon my poor ascii-art):

 A<- B
 |   ^
 \   /
  ->C

we can break that by abstracting D from any class:

  >D
 /  ^
 A  |
 ^  |
 |  |
 B  |
 ^  |
 |  |
 C-/

which, if C's dependence on B was inheritance, is MI for C. Of course there are other ways to do this refactoring, but MultipleInheritance is the most economical one.

There's an interesting thing about this technique: the choice of which class to factor from is always natural. I mean, in my experience, it's just bleeding obvious. This backs an idea first suggested to me by MikeMowbray.

If you have a long-chain cyclic dependence inherent in a class diagram, then that always means there's a class hiding in there some place that you need to factor out.

The technique I use to do this is pretty simple: in a class diagram, make all the arcs point up. That's to say, if one class is higher on the page than another, then the lower class can use/inherit/composite/aggregate/whatever the higher class, but not vice versa. This puts a lot of extra information on a class diagram, because it's not just the arcs that convey information - position of classes becomes extremely useful information about what those classes can and cannot be responsible for.

Hmm ... I wonder what the CRC equivalent would be? --PeterMerel

OK ... now what is "compile-time"? ;->RonJeffries

Another typical smalltalk programmer's response :-)


(AnswerMe) "changing the interface to A requires changing the interface to B which requires changing the interface to C ... which requires changing the interface to A again" - huh? I simply cannot imagine that happening at all. Please give an example. --AndersMunch


EditText of this page (last edited June 22, 2005) or FindPage with title or text search