Come evitare riferimenti circolari in OOP Javascript?

2

Ho un problema mentre lavoro con l'entity framework in JavaScript. Ho due classi Table e Column

Class Table {
Columns: Column[]
}

Class Column {
Parent: Table
}

Tutto funziona bene finché non uso la funzione toJSON che ho implementato per la classe Base (sia Table che Column ereditano da Base). Questa funzione passa semplicemente attraverso tutte le proprietà di un'istanza e la analizza nella stringa JSON. Questo è per scopo di persistenza. Ma toJSON in questo caso causerà un ciclo continuo da colonna a tabella e ritorno a colonna.

Qualunque esperto là fuori potrebbe aiutarmi in questo?

    
posta Phương Lâm 16.05.2016 - 20:32
fonte

2 risposte

3

Da quanto hai descritto, non hai affatto bisogno di un riferimento circolare, quindi la cosa migliore che puoi fare è eliminarla completamente.

in Column class I have a build function which return a string by combining table and column like "tableA.colB". That why column need to know what table it belong to.These entities are used for building SQL statement.

Questo è un segno che la tua funzione build non appartiene alla classe Column. Pensaci: perché una singola colonna nel tuo database è l'oggetto responsabile della creazione di parte di un'istruzione SQL? Probabilmente vorresti fare l'SQL building in una classe completamente separata che è stata effettivamente progettata per quello scopo.

class SQLBuilder {
    build: function(table, column) {
        return ... + table.name + "." + column.name + ...;
    }
}

Se per qualche ragione questa non è un'opzione, ci sono trucchi che puoi ricorrere a come memorizzare il nome della tabella genitore invece di un riferimento diretto (che ha la maggior parte dei lati negativi di un riferimento circolare reale diverso da "rottura" "toJSON), o l'implementazione della logica di serializzazione personalizzata (che è davvero noiosa e soggetta a errori da mantenere), ma non dovresti fare cose del genere a meno che tu non abbia una buona ragione per farlo.

    
risposta data 16.05.2016 - 22:29
fonte
1

Il modo più semplice, come menzionato nei commenti, è rimuovere il riferimento Parent da Column come menzionato nei commenti. Puoi quasi certamente ricodificare per fornire sia la tabella che la colonna come coppia (anziché solo la colonna) dove necessario.

Il prossimo modo più semplice è cambiare il contenuto di Parent in Columns da un riferimento a un oggetto di qualche tipo, sia un intero il cui valore corrisponde a un indice in un array di tabelle, o una stringa che contiene l'ID univoco o il nome del tavolo. Ciò significa che i tuoi usi di column.Parent , se hanno bisogno di accedere all'intera tabella, dovranno essere racchiusi in una funzione che comprenda come tradurre l'indice o la stringa nel genitore.

Si noti che se i nomi delle tabelle sono univoci e questo è tutto ciò che serve da column.Parent , allora forse convertire questi campi da un riferimento (circolare) a un altro oggetto in una stringa che identifica il nome della tabella funzionerà meglio per te.

Il prossimo metodo è di fornire un toJSON() personalizzato per i tipi Column in modo che alterino il campo Parent per la serializzazione, alterandolo da un riferimento a un indice o stringa come sopra; questo avverrà solo durante JSON.stringify() invece che durante l'uso in memoria di quel campo. Naturalmente, per fare ciò dovrai anche creare o simulare un'operazione reviver durante / dopo JSON.parse() che capisce i riferimenti e li converte nuovamente negli oggetti.

    
risposta data 16.05.2016 - 21:19
fonte