Il y a plusieurs aspects à considérer dans une telle conception:
- les dépendances structurelles
- la relation de propriété (iecomposition vs autre type d'association)
- les besoins de navigation
Dépendance structurelle entre les classes:
Si vous visez à réutiliser des classes de composants, vous devez éviter les dépendances inutiles et éviter ces structures circulaires fermées.
Néanmoins, parfois, deux classes sont conceptuellement fortement liées. Dans ce cas, éviter la dépendance n'est pas une vraie option. Exemple: un arbre et ses feuilles, ou plus généralement un composite et ses composants .
Propriété des objets:
Un objet est-il propriétaire de l'autre? Ou autrement dit: si un objet est détruit, l'autre doit-il également être détruit?
Ce sujet a été abordé en profondeur par Snowman, donc je ne vais pas en parler ici.
Besoins de navigation entre les objets:
Un dernier problème est le besoin de navigation. Prenons mon exemple préféré, le motif de conception composite du Gang of four .
Gamma & al. mentionner explicitement le besoin potentiel d'avoir une référence parent explicite: "Le maintien de la référence des composants enfants à leur parent peut simplifier la traversée et la gestion d'une structure composite " Bien sûr, vous pourriez imaginer une traversée systématique de haut en bas, mais pour les très grands objets composites, il peut considérablement ralentir les opérations et de manière exponentielle. Une référence directe, même circulaire peut faciliter considérablement la manipulation de vos composites.
Un exemple pourrait être un modèle graphique d'un système électronique. Une structure composite pourrait représenter les cartes électroniques, les circuits, les éléments. Pour afficher et manipuler le modèle, vous auriez besoin de proxys géométriques dans une vue GUI. Il est alors certainement beaucoup plus facile de naviguer de l'élément GUI sélectionné par l'utilisateur vers le composant, pour savoir quel est le parent et avec quels sont les éléments frère / sœur associés, que de lancer une recherche descendante.
Bien sûr, comme Gamma & al l'a souligné, vous devez vous assurer des invariants de la relation circulaire. Cela peut être délicat, comme l'a montré la question SO à laquelle vous vous référez. Mais c'est parfaitement gérable et d'une manière sûre.
Conclusion
Le besoin de navigation ne doit pas être sous-estimé. Ce n'est pas sans raison que UML l'a explicitement adressé dans la notation de modélisation. Et oui, il existe une situation parfaitement valable où des références circulaires sont nécessaires.
Le seul point est que parfois les gens ont tendance à aller trop vite dans une telle direction. Il vaut donc la peine de considérer tous les 3 aspects impliqués avant de prendre la décision d'y aller ou non.