As far as I know, circular dependencies are something to be avoided, yet I find myself often in a situation where I've got some Object
, and an ObjectManager
, that is supposed to "oversee" all the Object
s, and provide methods to aggregate these Object
's and so on.
Example:
Object
that has aposition
and can move itselfObjectManager
with methods likegetAllObjects
andgetAllObjectsAtPosition(x, y)
ObjectManager
needs to have a list of Object
references, and Object
needs a reference to ObjectManager
, so it can notify the ObjectManager
that it has changed its position (so ObjectManager
can, for example, update its hashmap with position : Object
pairs, so getAllObjectsAtPosition
is not linear)
Does it make to have a circular dependency here? If not, how should it be avoided?
-
One solution would be to put a GetPosition() function on the Object which is called by the ObjectManager when the manager needs to know positions. (see "The Hollywood Principle" thephantomprogrammer.blogspot.com/2015/08/…)user362602– user3626022021年04月22日 09:46:58 +00:00Commented Apr 22, 2021 at 9:46
1 Answer 1
Yes, circular dependencies are bad. The reason for that is you can't really change or even understand the one without the other, which kills maintainability.
Second, there are lots of ways to solve a circular dependency, but none is really generic. So you'll have to design your way around it case by case.
With your positions example, I offer you these alternatives:
- Try to get the position out of
Object
, so it's only inObjectManager
. - Have the
ObjectManager
wrap all returnedObject
references with a Facade that updatesObjectManager
's own positions map when amove
(or similar) is called on individualObject
s. - Couple the
Object
withObjectManager
through an indirection, like a "listener" interface or event bus, or similar. I would note this complicates things significantly, so it should be the very last resort. This is basically "inverting" the dependencies in one direction. - Have the
Object
itself be a part of (inner class of)ObjectManager
. - Design the whole thing differently, find different abstractions.
Also note that Object
and ObjectManager
are really bad names, I assume you picked those just for demonstrating the hierarchical relationship between them. Don't actually name things "Manager", that's so 2000s. :)
-
Thank you. Also, I wanted
Object
to fire an event whenever it changes its position, rather than keep an explicit reference to the manager.ObjectManager
would listen to these events. I assume this is the third option on your list?John Smith– John Smith2021年04月19日 11:50:22 +00:00Commented Apr 19, 2021 at 11:50 -
1Yes, that's what I've meant. Again, having events still creates a coupling, and now this coupling is less visible. So it's a trade-off.Robert Bräutigam– Robert Bräutigam2021年04月19日 11:59:57 +00:00Commented Apr 19, 2021 at 11:59