2014-11-07 20 views
5

Ho bisogno di sapere perché dobbiamo evitare le dipendenze circolari? Nel mondo reale, se pensiamo, le dipendenze circolari sono piuttosto importanti. Come un amico ha bisogno di qualcosa da un altro amico e l'altro ha bisogno di qualcosa da questo amico, quindi il suo tipo di circolare vero?La dipendenza circolare è buona o cattiva

Allora perché la dipendenza circolare è un cattivo progetto? Se davvero dobbiamo evitare questo, qual è il miglior design possibile nel mondo orientato agli oggetti per una situazione del genere?

+1

Nella mia esperienza il problema principale con i riferimenti circolari è la gestione della memoria - chi possiede cosa? –

+0

Non è né buono né cattivo: è quello che è. Se ti senti necessario, fai attenzione alle perdite di memoria. – YvesLeBorg

+0

l'ultima volta che ho controllato (alias ho dovuto compilarlo) il progetto 'llvm' era all in per le dipendenze circolari e stanno scrivendo una macchina virtuale/un compilatore. Puoi prenderlo come esempio e magari chiedere perché stanno andando con quel design. – user2485710

risposta

7

Il problema delle dipendenze circolari è piuttosto simile al problema dell'uovo e della gallina.

Se dipendi da me che sto preparando qualcosa, e dipendo dal fatto che tu stia preparando qualcosa, come possiamo iniziare?

Il corollario di questo è come possiamo finire - se ho un riferimento alla vostra risorsa e si dispone di un riferimento al mio, non riesco mai a pulire perché sarebbe rompere voi, e non è possibile pulire perché sarebbe rompere me.

La risposta in entrambi i casi è di introdurre un intermediario, passando la dipendenza da una delle parti a lui, quindi se passassi la tua risorsa a un intermediario, dipenderesti da me e dall'intermediario, e io dipenderei sull'intermediario Quindi puoi ripulire perché ora non hai risorse e posso pulire perché nessuno dipende da me, e quindi l'intermediario può ripulire.

+0

buona risposta generica, evita le insidie ​​di do-hick specifici del linguaggio che possono gestire parte di quella complessità e uno schema utile in tutti i casi che conosco. +1 – YvesLeBorg

+0

hmmm grazie gbjbaanb. Ma significa anche che nel mondo virtuale 2 amici non possono interagire direttamente tra loro, avranno bisogno di un intermediario per farlo – Nipun

+0

È ancora possibile comunicare, non è possibile * dipendere * dall'altra. Quindi, una volta che hai una tale configurazione, devi aspettarti che il partner non sia presente. È l'accoppiamento stretto che conta nelle dipendenze circolari. – gbjbaanb

2

È necessario rendersi conto che una dipendenza circolare implica che è possibile utilizzare solo le corrispondenti classi dipendenti circolari insieme: se si dispone di una dipendenza circolare tra, diciamo, A e B, non è possibile utilizzare A o B indipendentemente in qualsiasi programma. Affrontare il tuo problema: sicuramente non hai bisogno che gli altri due amici esistano! Tutto ciò di cui hai bisogno è un modo per fare riferimento ad alcuni e interagire con loro in un modo che può essere limitato rispetto alle loro effettive abilità.

Tuttavia, è spesso possibile che oggetti delle classi si utilizzino l'un l'altro senza causare una dipendenza circolare. A tal fine è importante determinare ciò che effettivamente causa una dipendenza tra due classi/componenti (questi non sono del tutto equivalenti, ma fornire una definizione approfondita sarebbe piuttosto lunga). A dipende B in queste condizioni:

  1. Quando A contiene un membro di tipo B.
  2. Quando A deriva da tipo B.
  3. Se A utilizza un valore di tipo B come parte di una firma di funzione.
  4. Quando A utilizza B nella sua implementazione.
  5. Probabilmente dimentico qualcosa qui (ricordo che c'erano più motivi per cui le classi sarebbero state accoppiate).

Quando si ha una dipendenza ciclica tra due classi, ci possono essere modi per rompere questa dipendenza. Spesso, la dipendenza può essere interrotta dividendo una delle due classi in una classe base e una classe derivata con la classe base non dipendente dall'altra classe. Esistono numerosi altri approcci per interrompere i cicli di dipendenza. "Large Scale C++" (1996) di John Lakos riguarda essenzialmente i cicli di dipendenza da rotture e motiva il motivo per cui le dipendenze cicliche sono cattive (credo, non sarebbe d'accordo con questa semplificazione della caratterizzazione).

...e, sì, le dipendenze cicliche sono male:

  1. Sono causa di programmi per includere funzionalità non necessarie perché le cose sono trascinati in cui non sono necessari.
  2. Rendono molto più difficile testare il software.
  3. Rendono molto più difficile ragionare sul software.
  4. Rendono molto più difficile sostituire parti del sistema.
  5. ... e probabilmente una serie di altri motivi.

Quanto sopra è stato formulato con una vista presa da una prospettiva C++. Alcune delle cause delle dipendenze circolari potrebbero non esistere [direttamente] in C, ma gli stessi concetti si applicano approssimativamente anche a C.

Problemi correlati