La dipendenza circolare esiste logicamente o fisicamente e può essere rotta con gli ID?

0

Si è quindi verificato un problema con dipendenza circolare simile a questa:

public class A
{
    public List<B> Bs { get; private set;}

    public void AddB(B b)
    {
        Bs.Add(b);
    }

    public void RemoveB(B b)
    {
        Bs.Remove(b);
    }

    public int DoWork()
    {
        // Need details of B
        // Probably need to inject a service that gets B details...
    }
}

public class B
{
    public A A1 { get; private set; }
    public A A2 { get; private set; }

    public B(A a1, A a2)
    {
        A1 = a1;
        A2 = a2;
    }

    public void ChangeA1(A a1)
    {
        A1.RemoveB(this);
        A1 = a1;
        A1.AddB(this);
    }

    public void ChangeA2(A a2)
    {            
        A2.RemoveB(this);
        A2 = a2;
        A2.AddB(this);
    }
}

Questo crea un'enorme dipendenza circolare e fa sì che l'intero grafo dell'oggetto venga letto in memoria (più volte). Quindi la mia domanda è: può / dovrebbe questa dipendenza circolare essere rotta fisicamente ed essere ancora bene logicamente?

Ad esempio, usando gli ID di As e Bs? Ovviamente saranno logicamente dipendenti l'uno dall'altro a livello logico, ma fisicamente non sarà necessario per l'intero grafico dell'oggetto da leggere in memoria.

Penso che questo non sia ancora intelligente perché la mia classe A avrebbe bisogno dei dettagli di B per eseguire il suo lavoro, quindi sarebbe necessario iniettare qualche tipo di servizio / repository. Presumo che il migliore refactoring sarebbe quello di introdurre un terzo oggetto per rompere la dipendenza circolare.

Sto cercando di risolvere il problema con un terzo oggetto o usando oggetti valore, ma un caso d'uso sarebbe quello di eliminare un B da A (quindi ho bisogno di sapere quale B cancellare (cioè avere un identità)).

Questo è il concetto generale di ciò che sto cercando di implementare. È per un sistema di contabilità a partita doppia che assomiglia a questo:

Per chiarire, A sarebbe un account e B sarebbe una transazione.

Quindi l'utente può visualizzare le transazioni dalla vista dell'account e quindi eliminare una transazione o rimuovere una divisione diversa. Quindi sembra che sia necessaria una dipendenza circolare per questa capacità di navigazione.

    
posta keelerjr12 12.11.2018 - 17:32
fonte

1 risposta

2

Da quello che posso vedere nel codice che hai fornito, l'unica ragione per cui B ha bisogno di sapere su A è che quando vuoi spostare una B in una nuova A, sai quale A è attualmente in.

La tua attuale soluzione è semplice con il trucco che introduce questa dipendenza circolare. Esistono numerose altre soluzioni per evitare questa dipendenza circolare.

Una semplice opzione è quella di iterare semplicemente su tutti gli oggetti A e rimuovere l'oggetto B da qualsiasi A che lo contiene. Utilizzando una struttura diversa per memorizzare i Bs, è possibile evitare il tempo speso per iterare su ogni elemento di ciascuna lista. Tuttavia, dal momento che ogni B è in 2 come, non sembra funzionare qui.

Un'altra opzione è quella di mantenere una mappa / dict di tutti i Bs e in quale posizione. Puoi tenere due mappe per la divisione A1, A2. Questo potrebbe avere senso qui. Hai solo bisogno di capire dove vuoi mantenere queste mappe e assicurarti che tutte le modifiche siano gestite in modo coerente negli oggetti A e nelle mappe.

    
risposta data 12.11.2018 - 20:37
fonte

Leggi altre domande sui tag