Ci sono molti motivi per cui i globali sono malvagi in OOP .
Se il numero o le dimensioni degli oggetti che richiedono la condivisione sono troppo grandi per essere passati in modo efficiente nei parametri di funzione, in genere tutti raccomandano Iniezione di dipendenza invece di un oggetto globale.
Tuttavia, nel caso in cui quasi tutti debbano conoscere una determinata struttura di dati, perché la Dependency Injection è migliore di un oggetto globale?
Esempio (uno semplificato, per mostrare il punto in generale, senza scavare troppo in profondità in un'applicazione specifica)
Esiste un numero di veicoli virtuali che hanno un numero enorme di proprietà e stati, da tipo, nome, colore, velocità, posizione, ecc. Un numero di utenti può controllarli a distanza e un numero enorme di eventi ( sia avviato dall'utente che automatico) può modificare molti dei loro stati o proprietà.
La soluzione ingenua sarebbe semplicemente creare un contenitore globale, come
vector<Vehicle> vehicles;
a cui è possibile accedere da qualsiasi luogo.
Più la soluzione OOP-friendly sarebbe quella di avere il contenitore membro della classe che gestisce il ciclo degli eventi principale, e di essere istanziato nel suo costruttore. Ogni classe che ne ha bisogno, ed è membro del thread principale, avrà accesso al contenitore tramite un puntatore nel suo costruttore. Ad esempio, se un messaggio esterno arriva tramite una connessione di rete, una classe (una per ogni connessione) che gestisce l'analisi prenderà il sopravvento e il parser avrà accesso al contenitore tramite un puntatore o un riferimento. Ora se il messaggio analizzato risulta in una modifica di un elemento del contenitore o richiede alcuni dati da esso per eseguire un'azione, può essere gestito senza la necessità di sballottare migliaia di variabili attraverso segnali e slot (o peggio, memorizzandoli nel parser per essere poi recuperati da colui che ha chiamato il parser). Naturalmente, tutte le classi che ricevono l'accesso al contenitore tramite l'iniezione di dipendenza, fanno parte dello stesso thread. Thread diversi non accedono direttamente a questo, ma fanno il loro lavoro e poi inviano segnali al thread principale, e gli slot nel thread principale aggiorneranno il contenitore.
Tuttavia, se la maggior parte delle classi avrà accesso al contenitore, cosa lo rende davvero diverso da un globale? Se così tante classi hanno bisogno dei dati nel contenitore, non è il "modo di iniezione delle dipendenze" solo un mondo mascherato?
Una risposta sarebbe la sicurezza del thread: anche se mi preoccupo di non abusare del contenitore globale, forse un altro sviluppatore in futuro, sotto la pressione di una scadenza ravvicinata, utilizzerà comunque il contenitore globale in un thread diverso, senza prendere cura di tutti i casi di collisione. Tuttavia, anche nel caso di un'iniezione di dipendenza, si potrebbe dare un puntatore a qualcuno che sta correndo su un altro thread, portando agli stessi problemi.