Riferimenti all'interfaccia circolare

3

Ho sentito che i riferimenti circolari sono in genere un problema, tuttavia mi chiedevo se questo fosse vero per le interfacce che fanno riferimento ad altre interfacce, ad esempio:

IQuestion{
    IAnswer getCorrectAnswer();
    IList<IAnswer> getAllAnswers();
}

IAnswer{
    IQuestion getQuestionInResponseTo();
}

C'è qualche caso in cui questo sarebbe un problema? Non mi sembra di essere risolvibile, se lo fosse. La mia ipotesi migliore è che questo non sarebbe un problema in quanto le interfacce non richiedono molto in termini di referenziazione. Grazie in anticipo.

    
posta Aidan Connelly 06.04.2018 - 17:10
fonte

4 risposte

5

È un problema, a patto che sia necessario verificare l'integrità / validità di entrambi i riferimenti non appena uno di essi cambia (e potrebbe voler controllare la possibile ricorsione infinita in questo modo). Poiché sembrano essere piuttosto statici, non è (molto) un problema; probabilmente dovresti ricontrollarlo durante la costruzione degli oggetti del modello. Ma non dimenticare di farlo. Non vuoi che la domanda A faccia riferimento alla risposta A e risponda a una domanda di riferimento B come "genitore".

Un po 'fuori tema: perché mantenere entrambi i riferimenti? È solo per risparmiare un po 'di tempo per ottenere la domanda a cui una risposta appartiene? Penso che nei contesti in cui probabilmente useresti la domanda e le sue risposte, il contesto ha già i riferimenti sia alla domanda sia alle risposte, quindi la relazione non dovrebbe essere difficile da estrarre da esse e renderebbe il tuo modello Progettare molto meno incline agli errori e più facile da mantenere.

    
risposta data 06.04.2018 - 19:05
fonte
2

Non penso che sia tecnicamente un riferimento circolare. Si compilerà.

Ma ci sono alcuni problemi di cui dovresti essere a conoscenza con questo tipo di struttura. Ad esempio la serializzazione.

Un approccio ingenuo potrebbe portare a un ciclo infinito se si fa riferimento all'oggetto padre.

Inoltre potresti dover considerare un valore nullo. Se hai un albero di questi oggetti l'ultima foglia avrà un valore nullo.

Eviterei tali strutture al di fuori di quelle progettate specificamente per un albero, una lista concatenata o una ricorsione.

Dove vuoi solo un facile riferimento all'oggetto genitore, preferirei passare in rassegna i genitori per trovarlo.

    
risposta data 06.04.2018 - 19:22
fonte
1

È chiaramente un riferimento circolare a livello delle interfacce. Simile ai tipi di dati ricorsivi, che hanno riferimenti circolari a livello di testo, non significa necessariamente che gli oggetti di istanza siano essi stessi impegnati in riferimenti circolari (sebbene possano certamente esserlo).

In molte circostanze (ma certamente non tutte), non c'è nulla di "sbagliato" con riferimenti circolari, anche se generalmente mostreranno qualche costruzione e amp; problemi di ordine di distruzione (cioè precludere alcuni degli oggetti istanza coinvolti dall'essere oggetti immutabili).

Può aiutare ad avere un'idea di genitore e figlio. Mentre il genitore fa riferimento ai figli e il bambino fa riferimento al genitore, di solito concordiamo che l'eliminazione di un figlio elimina solo (il bambino stesso e) l'unico riferimento genitore-figlio (e non il genitore stesso), mentre l'eliminazione del genitore può significare l'eliminazione non solo i riferimenti genitore-figlio, ma anche tutti i suoi attuali figli.

Ciò significa che il genitore & i riferimenti dei bambini sono direzionali e asimmetrici, e in un certo senso, uno è effettivamente "più strong" dell'altro nonostante la circolarità, poiché uno include una nozione di proprietà che l'altro non possiede.

Mentre alcuni database ci permettono di specificare questa "forza" come espressione di costrizione; i nostri linguaggi di programmazione, al contrario, non ci permettono per lo più di distinguere tra riferimenti da genitore a figlio e da figlio a genitore (sono entrambi solo riferimenti). Se consentissero tale differenziazione, potremmo considerare i riferimenti genitore / figlio e figlio / genitore come non circolari alla luce della loro natura asimmetrica.

Alcuni algoritmi di conteggio dei riferimenti interrompono i cicli tramite riferimenti forti implicitamente marcati o esplicitamente dichiarati.

Nel piccolo, i cicli non sono poi così male quando si usa un linguaggio spazzato. Per la gestione manuale della memoria, tuttavia, in particolare il conteggio dei riferimenti, i cicli sono un problema.

Nel grande, come quando arriviamo ai cicli nelle librerie (una libreria dipende da un'altra che dipende da essa ...), queste possono essere problematiche in particolare per quanto riguarda l'ordinamento di inizializzazione. Tali problemi tendono ad essere esacerbati per le circolarità tra componenti di sistemi operativi come driver e / o sottosistemi: non che non possa essere fatto ma aumenta la complessità, ostacolando allo stesso tempo la possibilità di subsetting: creare una versione più piccola del sistema operativo per un minore ambiente.

    
risposta data 06.04.2018 - 21:32
fonte
0

È solo un problema se usi un linguaggio in cui i riferimenti circolari possono causare perdite di memoria (come C ++) o se stai facendo qualcosa come caricare questi oggetti da un database e finire in un ciclo infinito se il tuo ORM non è a conoscenza di come gestirlo correttamente. Tutti i problemi di cui sono a conoscenza possono essere elaborati fino a quando ne viene a conoscenza, utilizzando elementi come puntatori deboli / non proprietari o inizializzazione pigra.

    
risposta data 06.04.2018 - 18:20
fonte