Design for circular dependency

Viewed 808

This is a question about how to better handle circular dependency. Let me preface by saying I think circular dependency is rarely necessary, but the code is handed down to me and I can't help it.

Suppose there is a circular dependency on classes with a conceptually equal standing, ie there is no apparent "owns" relation between them. How do I handle them gracefully?

Lets take an example where we want to represent a mutable topology of rooms, with neighbour a reflexive property

interface Room {
    public void remove(Room r);
}

class Living implements Room {
    Room[] neighbour;
    public void remove(Room r) {/* implementation */}
}

class Dining implements Room {
    Room[] neighbour;
    public void remove(Room r) {/* implementation */}
}

Now, clearly we cannot call remove on the other Room in the implementation of remove, this is obviously endless recursion. But then I am left with a few options:

  • Make one Room own another, somehow document the fact, and then only one type of Room has the remove capability.
  • Make a second method removeSelf, where it never calls the methods of the other Room, thereby resolving the infinite recursion.
  • Have a Building object higher on the hierarchy and have it do all the operations on Room

And their respective disadvantages are

  • Very counter-intuitive and imposes an artificial structure when there is none. Also, at least one owning Room must exist within some neighbour.
  • Adds a method that should never be called by users, this sucks as an interface.
  • Requires an owning object, sometimes also a very awkward structure, a Building is only coincidentally fitting to be an owning object.

So, the question, what is a better design if circular dependency is somehow unavoidable?

We could probably make a RoomOperator class containing functions to operate on Rooms, but it also suffers the same problems as the removeSelf method above: it eventually calls a method that is illegal outside of RoomOperator.

2 Answers
Related