Home > Mobile >  Is there a use case for having a class A contain an instance of class B, and B an instance of A?
Is there a use case for having a class A contain an instance of class B, and B an instance of A?

Time:12-18

This rings the "circular dependency" bell in my head. But I was wondering if there are known accepted use cases for this.

Just to illustrate with some Python:

class A:
    pass


class B:
    pass


a = A()
b = B()

a.b = b
b.a = a

Can we ever make the case for this being the ideal implementation for something? In other words, will you ever find this pattern recommended in a good programming book?

CodePudding user response:

  • Every car has a steering wheel while every steering wheel belongs to a car.
  • Every building has an address while every address refers to a building.
  • ...

The question is, I think, should you really contain the entire class, or just a reference towards it? (I honestly believe that a reference should be sufficient in most cases)

CodePudding user response:

In many languages, classes have a reference semantic. In this case, an A does not contain a B instance nor a B an A instance, but both instances refer to each other. This is a very common implementation of an association with bidirectional navigation:

enter image description here

A typical variant is when the association is one-to-many, or many-to-many, like Student and Course. It's exactly the same problem, except that at least one of the class contains a collection of the other. Also a very common case.

You are right that this may create a circular dependency. But if can be easily managed when the classes do only need to know the reference of the other. In stricter languages, where the class needs to know the full class definition, the circular dependency can be prevented using interfaces.

In some languages classes have value semantic (or only some types like struct in C#). Such a mutual containment is then not possible because of the endless recursive containment it would require. C is such a language, and the design would then require to break the mutual containment with (smart) pointers or references (at least on one side).

  • Related