Come eliminare un oggetto quando altre cose lo fanno riferimento (e non rendere il codice pieno di interdipendenze)

4

La situazione:

Nel mio programma, ci sono una lista di segnali. Per chiamare una stecca in un dato momento, ci sono oggetti chiamati Trigger. Gli spunti hanno molti metodi pubblici che consentono loro, tra le altre cose, di essere "licenziati" (il che li induce a compiere un'azione). Attiva i segnali di "fuoco" quando vengono attivati. Lo fanno prendendo un riferimento alla Cue e chiamando Cue.fire (). I trigger sono tutti memorizzati in una classe chiamata TriggerManager che li mantiene in un elenco di array. Le spie fanno parte di un elenco collegato tra loro. Quindi, in estate: i Trigger sanno di Cues, ma gli spunti non conoscono i trigger; I trigger chiamano segnali in determinati momenti.

Il problema:

Quando rimuovo una Cue dall'elenco collegato, è ancora "vivo" / non è stato raccolto in modo errato perché c'è un Trigger con un riferimento ad esso. La cosa naturale sarebbe eliminare il Trigger, ma questo crea una serie di problemi che devono essere risolti:

Il principale è questo: dato che la Cue non conosce il Trigger che lo fa riferimento, come faccio a ottenerlo per cancellarlo. (Soprattutto dal suo riferimento a una classe TriggerManager). Ci deve essere un modo per farlo senza che Cues dipenda da Trigger e Trigger dipendenti dai loro TriggerManager o Cue dipendenti da TriggerManagers, che non dovrebbero avere nulla a che fare con Cues (Dare un riferimento bidirezionale all'altro renderà il codice complicato e difficile da tenere traccia di)

Domanda: C'è una soluzione che risolverà il mio problema mantenendo il codice gestibile? Il mio design è intrinsecamente imperfetto? In tal caso, come posso risolverlo?

    
posta sinθ 06.06.2013 - 23:57
fonte

2 risposte

1

L'elenco collegato non ti sta davvero aiutando qui. Sostituiscilo con un CueManager che

  1. Contiene l'elenco di Cue
  2. Associa le spie ai rispettivi trigger

CueManager dovrebbe quindi controllare il ciclo di vita delle Cue - aggiungendole e rimuovendole dai rispettivi trigger.

interface CueManager {
  public addCueToTrigger(Cue, Trigger);
  public removeCueFromTrigger(Cue, Trigger);
  public deleteCue(Cue);
}
    
risposta data 07.06.2013 - 00:19
fonte
1

Il mio primo pensiero era una sorta di modello di pubblicazione / sottoscrizione e / o callback, ma che viola il tuo obbligo di evitare riferimenti bidirezionali.

Un'alternativa potrebbe essere quella di aggiungere un flag "cueIsAlive" alla Cue. Impostalo su true nel costruttore, chiedi a RemoveFromLinkedList() call di impostarlo su false e utilizzalo nel tuo metodo Cue.Fire() :

public void Fire() {
    if (this.cueIsAlive) {
        ... execute Fire code ...
    }
}

Non sono sicuro che questo possa essere considerato un oggetto zombi o no - l'idea di base è renderla innocua fino al momento in cui può essere raccolta.

    
risposta data 07.06.2013 - 03:38
fonte

Leggi altre domande sui tag