Hay muchas razones por las cuales los globales son malvados en OOP.
Si el número o el tamaño de los objetos que necesitan compartirse es demasiado grande para pasarlo de manera eficiente en los parámetros de la función, generalmente todos recomiendan la inyección de dependencia en lugar de un objeto global.
Sin embargo, en el caso de que casi todos necesiten saber sobre una determinada estructura de datos, ¿por qué la inyección de dependencias es mejor que un objeto global?
Ejemplo (uno simplificado, para mostrar el punto en general, sin profundizar demasiado en una aplicación específica)
Hay una serie de vehículos virtuales que tienen una gran cantidad de propiedades y estados, desde tipo, nombre, color, velocidad, posición, etc. Varios usuarios pueden controlarlos de forma remota y una gran cantidad de eventos (ambos iniciado y automático) puede cambiar muchos de sus estados o propiedades.
La solución ingenua sería hacer un contenedor global de ellos, como
vector<Vehicle> vehicles;
que se puede acceder desde cualquier lugar.
La solución más amigable para OOP sería hacer que el contenedor sea miembro de la clase que maneja el bucle de eventos principal y que se cree una instancia en su constructor. Cada clase que lo necesite, y sea miembro del hilo principal, tendrá acceso al contenedor a través de un puntero en su constructor. Por ejemplo, si llega un mensaje externo a través de una conexión de red, se hará cargo de una clase (una para cada conexión) que maneja el análisis y el analizador tendrá acceso al contenedor a través de un puntero o referencia. Ahora, si el mensaje analizado produce un cambio en un elemento del contenedor, o requiere algunos datos para realizar una acción, se puede manejar sin la necesidad de arrojar miles de variables a través de señales y ranuras (o peor, almacenarlos en el analizador para luego ser recuperado por quien llamó al analizador). Por supuesto, todas las clases que reciben acceso al contenedor a través de la inyección de dependencia, son parte del mismo hilo. Diferentes hilos no accederán directamente a él, pero harán su trabajo y luego enviarán señales al hilo principal, y las ranuras en el hilo principal actualizarán el contenedor.
Sin embargo, si la mayoría de las clases tendrán acceso al contenedor, ¿qué lo hace realmente diferente de un global? Si tantas clases necesitan los datos en el contenedor, ¿no es la "forma de inyección de dependencias" simplemente un global disfrazado?
Una respuesta sería la seguridad de los subprocesos: aunque me preocupo de no abusar del contenedor global, tal vez otro desarrollador en el futuro, bajo la presión de un plazo cercano, utilice el contenedor global en un subproceso diferente, sin ocuparme de todo Los casos de colisión. Sin embargo, incluso en el caso de la inyección de dependencia, se podría dar un puntero a alguien que se ejecuta en otro hilo, lo que lleva a los mismos problemas.