Java – How to delete an object when other things reference it (and not making the code full of inter-dependencies)

designdesign-patternsjavaprogramming practices

The situation:

In my program, there are a list of cues. To call a cue at a certain time, there are objects called Triggers. Cues have many public methods that allow them, among other things, to be "fired" (which causes them to perform an action). Triggers "fire" cues when they are activated. They do this by taking a reference to the Cue and then calling Cue.fire(). The triggers are all stored in a class called TriggerManager which keeps them in an array list. Cues are part of a linked list with eachother. So, in summery: Triggers know about Cues, but Cues don't know about triggers; Triggers call cues at certain times.

The problem:

When I remove a Cue from the linked list, it's still "alive"/hasn't been garbage collected because there's a Trigger with a reference to it. The natural thing would be to delete the Trigger, but that creates a host of issues that need to be solved:

The main one is this: Since, the Cue doesn't know about the Trigger that references it, how do I get it to be deleted. (Especially since its referenced by a TriggerManager class). There has to be a way to do this without making Cues dependent on Triggers and Triggers dependent on their TriggerManagers OR Cues dependent on TriggerManagers, which should have nothing to do with Cues (Giving everything a bidirectional reference to each other will make the code complicated and hard to keep track of)

Question: Is there a solution that will fix my problem while keeping the code manageable? Is my design inherently flawed? If so, how do I fix it?

Best Answer

The linked list isn't really helping you here. Replace it with a CueManager that

  1. Contains the list of Cues
  2. Maps the Cues to their respective Triggers

The CueManager should then control the life-cycle of the Cues--adding them and removing them from their respective triggers.

interface CueManager {
  public addCueToTrigger(Cue, Trigger);
  public removeCueFromTrigger(Cue, Trigger);
  public deleteCue(Cue);
}
Related Topic