Say I have the following components:
- Producer produces numbers and sends messages to Consumer
- Both Producer and Consumer send messages to Monitor
- Monitor, say randomly, decides when the produce / consume process should stop and sends a message to Stopper
- Stopper then stops both Producer and Consumer cleanly
I know this is easy to accomplish in a mutable language such as Java. I know also this can be resolved by allowing partial mutability with interfaces, such as described here.
However, it's not a good practice to have cyclic dependencies even if possible. So, let's assume all references are constructor-injected and final:
- Producer has
final Consumer
andfinal Monitor
- Consumer has
final Monitor
- Monitor has
final Stopper
- Stopper has
final Producer
andfinal Consumer
I found references such as this, but they don't seem to apply.
How would one go about un-cycling this case and cases such as this in general? In other words, I'm mostly interested in how to accomplish not forming the cycles from a design standpoint. Any hints?
You're right, this won't work if all dependencies are final and injected via the constructor.
But may I ask, why do they have to be injected via the constructor? There is nothing wrong at the end of the day to use
setters
to wire up beans.In fact, in Spring, beans are usually instantiated first and injected afterwards. So you could look at that approach.
Other than that, you could look at a different way to model your problem (that does not have circular dependencies).
For example, since you are using queues already to send messages between the producer and consumer, why not also send messages on queues to the monitor? The stopper could also send messages to the producer and consumer.
Or, as Taylor suggests, an ESB.
There are probably many other ways to design it, have a read about (for example) Apache Camel Enterprise Integration Patterns for some ideas.