Acabo de encontrarme con esta vieja pregunta preguntando qué hay de malo en el estado global, y la respuesta aceptada y más votada afirma que no puede confiar en ningún código que funcione con variables globales, porque algún otro código en algún otro lugar podría aparecer y modificar su valor y luego no sabes cuál será el comportamiento de tu código porque los datos son diferentes. Pero cuando miro eso, no puedo evitar pensar que es una explicación realmente débil, porque ¿en qué se diferencia eso de trabajar con datos almacenados en una base de datos?
Cuando su programa está trabajando con datos de una base de datos, no le importa si otro código en su sistema lo está cambiando, o incluso si un programa completamente diferente lo está cambiando, para el caso. No te importa cuáles son los datos; Ese es todo el punto. Lo único que importa es que su código maneja correctamente los datos que encuentra. (Obviamente, estoy pasando por alto el problema a menudo espinoso del almacenamiento en caché aquí, pero ignoremos eso por el momento).
Pero si los datos con los que está trabajando provienen de una fuente externa sobre la cual su código no tiene control, como una base de datos (o entrada del usuario, o un socket de red, o un archivo, etc.) y no hay nada de malo con eso, entonces, ¿cómo es que los datos globales dentro del código mismo, sobre los cuales su programa tiene un mayor grado de control, son algo malo cuando obviamente son mucho menos malos que cosas perfectamente normales que nadie ve como un problema?
Respuestas:
Primero, diría que la respuesta a la que se vincula exagera ese tema en particular y que el mal primario del estado global es que introduce el acoplamiento de formas impredecibles que pueden dificultar el cambio del comportamiento de su sistema en el futuro.
Pero profundizando en este tema aún más, hay diferencias entre el estado global en una aplicación orientada a objetos típica y el estado que se mantiene en una base de datos. Brevemente, los más importantes son:
Los sistemas orientados a objetos permiten reemplazar un objeto con una clase diferente de objeto, siempre que sea un subtipo del tipo original. Esto permite cambiar el comportamiento , no solo los datos .
El estado global en una aplicación generalmente no proporciona las fuertes garantías de coherencia que una base de datos: no hay transacciones durante las cuales se vea un estado coherente, ni actualizaciones atómicas, etc.
Además, podemos ver el estado de la base de datos como un mal necesario; Es imposible eliminarlo de nuestros sistemas. El estado global, sin embargo, es innecesario. Podemos eliminarlo por completo. Entonces, incluso si los problemas con una base de datos fueran igual de malos, aún podemos eliminar algunos de los problemas potenciales y una solución parcial es mejor que ninguna solución.
fuente
Primero, ¿cuáles son los problemas con las variables globales, según la respuesta aceptada a la pregunta que ha vinculado?
Las bases de datos son, la gran mayoría de las veces, compatibles con ACID. ACID aborda específicamente los problemas subyacentes que harían que un almacén de datos sea impredecible o poco confiable.
Esto se debe a que las variables globales existen en un ámbito muy alejado de su uso, tal vez incluso en un archivo diferente. Cuando utiliza una base de datos, está utilizando un conjunto de registros u objeto ORM que es local para el código que está leyendo (o debería ser).
Los controladores de bases de datos suelen proporcionar una interfaz coherente y comprensible para acceder a datos que son los mismos independientemente del dominio del problema. Cuando obtiene datos de una base de datos, su programa tiene una copia de los datos. Las actualizaciones son atómicas. Contraste con las variables globales, donde múltiples hilos o métodos pueden estar operando en el mismo dato sin atomicidad a menos que agregue la sincronización usted mismo. Las actualizaciones de los datos son impredecibles y difíciles de rastrear. Las actualizaciones pueden estar entrelazadas, lo que causa ejemplos de libros de texto estándar de pantanos de corrupción de datos multiproceso (por ejemplo, incrementos entrelazados).
Las bases de datos generalmente modelan datos diferentes que las variables globales para empezar, pero dejando eso de lado por un momento, las bases de datos están diseñadas desde cero para ser un almacén de datos compatible con ACID que mitigue muchas de las preocupaciones con las variables globales.
fuente
Ofrecería algunas observaciones:
Sí, una base de datos es un estado global.
De hecho, es un estado súper global, como usted señaló. Es universal! Su alcance implica cualquier cosa o persona que se conecte a la base de datos. Y sospecho que muchas personas con años de experiencia pueden contarte historias de horror sobre cómo las "cosas extrañas" en los datos llevaron a un "comportamiento inesperado" en una o más de las aplicaciones relevantes ...
Una de las posibles consecuencias del uso de una variable global es que dos "módulos" distintos usarán esa variable para sus propios fines distintos. Y hasta ese punto, una tabla de base de datos no es diferente. Puede ser víctima del mismo problema.
Hmm ... Aquí está la cosa:
Si un módulo no funciona extrínsecamente de alguna manera, no hace nada.
Un módulo útil puede recibir datos o puede encontrarlo . Y, puede devolver datos o puede modificar el estado. Pero, si no interactúa con el mundo externo de alguna manera, es mejor que no haga nada.
Ahora, nuestra preferencia es recibir datos y devolver datos. La mayoría de los módulos son simplemente más fáciles de escribir si se pueden escribir sin tener en cuenta lo que está haciendo el mundo exterior. Pero en última instancia, algo necesita encontrar los datos y modificar ese estado externo y global.
Además, en aplicaciones del mundo real, los datos existen para que puedan ser leídos y actualizados por varias operaciones. Algunos problemas se evitan mediante bloqueos y transacciones. Pero, en principio , evitar que estas operaciones entren en conflicto entre sí , al final del día, simplemente implica pensar cuidadosamente. (Y cometer errores ...)
Pero también, generalmente no estamos trabajando directamente con el estado global.
A menos que la aplicación viva en la capa de datos (en SQL o lo que sea), los objetos con los que trabajan nuestros módulos son en realidad copias del estado global compartido. Podemos hacer lo que queramos sin impacto en el estado real compartido.
Y, en los casos en que necesitamos mutar ese estado global, bajo el supuesto de que los datos que nos dieron no han cambiado, generalmente podemos realizar el mismo tipo de bloqueo que haríamos en nuestros globales.
Y finalmente, generalmente hacemos cosas diferentes con las bases de datos de lo que podríamos hacer con los globales traviesos.
Un mundo travieso y roto se ve así:
Simplemente no usamos bases de datos para cosas en proceso / operativas como esas. Y podría ser la naturaleza lenta de la base de datos y la relativa conveniencia de una variable simple lo que nos disuade: nuestra interacción lenta e incómoda con las bases de datos simplemente los convierte en malos candidatos para muchos de los errores que históricamente hemos cometido con las variables.
fuente
No estoy de acuerdo con la afirmación fundamental de que:
Mi pensamiento inicial fue "Wow. Just Wow". Se gasta mucho tiempo y esfuerzo tratando de evitar exactamente esto, y resolviendo qué compensaciones y compromisos funcionan para cada aplicación. Simplemente ignorarlo es una receta para el desastre.
Pero también estoy de acuerdo en un nivel arquitectónico. Una variable global no es solo un estado global. Es un estado global al que se puede acceder desde cualquier lugar de forma transparente. A diferencia del uso de una base de datos, debe tener un identificador (a menos que almacene el identificador en una variable global ...)
Por ejemplo, usar una variable global podría verse así
Pero hacer lo mismo con una base de datos debería ser más explícito sobre lo que está haciendo
La base de datos obviamente está jugando con una base de datos. Si no desea usar una base de datos, puede usar el estado explícito y se ve casi igual que el caso de la base de datos.
Entonces argumentaría que usar una base de datos es mucho más como usar un estado explícito que usar variables globales.
fuente
MakeNewThing
dependeMakeNewThingInDb
y mi clase de controlador usaMakeNewThing
, entonces no está claro en el código de mi controlador que estoy modificando la base de datos. Entonces, ¿qué pasa si uso otra clase que realmente confirma mi transacción actual a la base de datos? DI hace que sea muy difícil controlar el alcance de un objeto.El punto de que la única razón por la que no se puede confiar en las variables globales ya que el estado se puede cambiar en otro lugar es, en sí mismo, no una razón suficiente para no usarlas, de acuerdo (¡es una razón bastante buena!). Es probable que la respuesta describiera principalmente el uso en el que restringir el acceso de una variable a solo áreas de código que le preocupan tendría más sentido.
Sin embargo, las bases de datos son un asunto diferente, porque están diseñadas con el propósito de ser accedidas "globalmente", por así decirlo.
Por ejemplo:
Sin embargo, lo más importante es que las bases de datos tienen un propósito diferente que una variable global. Las bases de datos son para almacenar y buscar grandes cantidades de datos organizados, donde las variables globales sirven a nichos específicos (cuando es justificable).
fuente
O diferente de trabajar con un dispositivo interactivo, con un archivo, con memoria compartida, etc. Un programa que hace exactamente lo mismo cada vez que se ejecuta es un programa muy aburrido y bastante inútil. Entonces sí, es un argumento débil.
Para mí, la diferencia que marca la diferencia con respecto a las variables globales es que forman líneas de comunicación ocultas y desprotegidas. Leer desde un teclado es muy obvio y está protegido. Tengo que realizar una determinada llamada de función y no puedo acceder al controlador del teclado. Lo mismo se aplica al acceso a archivos, la memoria compartida y, por ejemplo, las bases de datos. Es obvio para el lector del código que esta función lee desde el teclado, que la función accede a un archivo, alguna otra función accede a la memoria compartida (y es mejor que haya protecciones al respecto), y aún otra función accede a una base de datos.
Con las variables globales, por otro lado, no es obvio en absoluto. La API dice que llame
foo(this_argument, that_argument)
. No hay nada en la secuencia de llamada que diga que la variable globalg_DangerWillRobinson
debe establecerse en algún valor, pero antes de llamarfoo
(o examinarla después de llamarfoo
).Google prohibió el uso de argumentos de referencia no constantes en C ++ principalmente porque no es obvio para el lector del código que
foo(x)
cambiaráx
porque esofoo
toma una referencia no constante como argumento. (Compare con C #, que dicta que tanto la definición de la función como el sitio de la llamada deben calificar un parámetro de referencia con laref
palabra clave). Si bien no estoy de acuerdo con el estándar de Google sobre esto, entiendo su punto.El código se escribe una vez y se modifica varias veces, pero si es bueno, se lee muchas, muchas veces. Las líneas de comunicación ocultas son muy mal karma. La referencia no constante de C ++ representa una línea de comunicación oculta menor. Una buena API o un buen IDE me mostrará que "¡Oh! Esta es una llamada por referencia". Las variables globales son una gran línea de comunicación oculta.
fuente
Creo que la explicación citada simplifica demasiado el tema hasta el punto en que el razonamiento se vuelve ridículo. Por supuesto, el estado de una base de datos externa contribuye al estado global. La pregunta importante es cómosu programa depende del estado global (mutable). Si una función de biblioteca para dividir cadenas en espacios en blanco dependiera de los resultados intermedios almacenados en una base de datos, me opondría a este diseño al menos tanto como me opondría a una matriz de caracteres global utilizada para el mismo propósito. Por otro lado, si decide que su aplicación no necesita un DBMS completo para almacenar datos comerciales en este momento y una estructura global de valor-clave en memoria funcionará, esto no es necesariamente un signo de diseño deficiente. Lo importante es que, independientemente de la solución que elija para almacenar sus datos, esta opción está aislada en una porción muy pequeña del sistema, por lo que la mayoría de los componentes pueden ser independientes de la solución elegida para el despliegue y la prueba de la unidad aislada y desplegada. La solución se puede cambiar en un momento posterior con poco esfuerzo.
fuente
Como ingeniero de software que trabaja predominantemente con firmware incorporado, casi siempre uso variables globales para cualquier cosa que vaya entre módulos. De hecho, es la mejor práctica para embebido. Se asignan de forma estática, por lo que no existe el riesgo de volar el montón / pila y no se necesita tiempo adicional para la asignación / limpieza de la pila en la entrada / salida de la función.
La desventaja de esto es que sí hay que tener en cuenta cómo se utilizan estas variables, y mucho de eso se reduce a la misma clase de pensamiento que entra en la base de datos-disputas. Cualquier lectura / escritura asíncrona de variables DEBE ser atómica. Si más de un lugar puede escribir una variable, se debe pensar en asegurarse de que siempre escriben datos válidos, de modo que la escritura anterior no se reemplace arbitrariamente (o ese reemplazo arbitrario es algo seguro). Si la misma variable se lee más de una vez, se debe pensar en lo que sucede si la variable cambia de valor entre lecturas, o se debe tomar una copia de la variable al inicio para que el procesamiento se realice utilizando un valor consistente, incluso si ese valor se vuelve obsoleto durante el procesamiento.
(Para el último, en mi primer día de un contrato trabajando en un sistema de contramedidas de aeronaves, tan altamente relacionado con la seguridad, el equipo de software estaba mirando un informe de error que habían estado tratando de resolver durante una semana más o menos. Tuve el tiempo justo para descargar las herramientas de desarrollo y una copia del código. Pregunté "¿no podría actualizarse esa variable entre lecturas y causarla?", Pero realmente no obtuve una respuesta. ¿Alguien nuevo sabe, después de todo? Entonces, mientras todavía lo discutían, agregué un código de protección para leer la variable atómicamente, hice una compilación local y básicamente dije "Hola chicos, intenten esto". Manera de demostrar que valía mi tasa de contratación . :)
Por lo tanto, las variables globales no son una cosa inequívocamente mala, pero lo dejan abierto a una amplia gama de problemas si no piensa en ellas con cuidado.
fuente
Dependiendo de qué aspecto esté juzgando, las variables globales y el acceso a la base de datos pueden estar muy separados, pero siempre que los juzguemos como dependencias, son lo mismo.
Consideremos que la definición de programación funcional de una función pura establece que debe depender únicamente de los parámetros que toma como entradas, produciendo una salida determinista. Es decir, dado el mismo conjunto de argumentos dos veces, debe producir el mismo resultado.
Cuando una función depende de una variable global, ya no se puede considerar pura, ya que, para el mismo conjunto o argumentos, puede producir resultados diferentes porque el valor de la variable global puede haber cambiado entre las llamadas.
Sin embargo, la función todavía puede verse como determinista si consideramos que la variable global es tan parte de la interfaz de la función como sus otros argumentos, por lo que no es el problema. El problema es solo que esto está oculto hasta el momento en que nos sorprende el comportamiento inesperado de funciones aparentemente obvias, luego lee sus implementaciones para descubrir las dependencias ocultas .
En esta parte, el momento en que una variable global se convierte en una dependencia oculta es lo que los programadores consideramos malvado. Hace que el código sea más difícil de razonar, difícil de predecir cómo se comportará, difícil de reutilizar, difícil de probar y, especialmente, aumenta el tiempo de depuración y reparación cuando se produce un problema.
Lo mismo sucede cuando ocultamos la dependencia de la base de datos. Podemos tener funciones u objetos que realicen llamadas directas a consultas y comandos de la base de datos, ocultando estas dependencias y causándonos exactamente el mismo problema que causan las variables globales; o podemos hacerlos explícitos, lo que, como resulta, se considera una práctica recomendada que tiene muchos nombres, como patrón de repositorio, almacén de datos, puerta de enlace, etc.
PD: Hay otros aspectos que son importantes para esta comparación, como si la concurrencia está involucrada, pero ese punto está cubierto por otras respuestas aquí.
fuente
Bien, comencemos desde el punto histórico.
Estamos en una aplicación antigua, escrita en su combinación típica de ensamblaje y C. No hay funciones, solo procedimientos . Cuando desea pasar un argumento o valor de retorno de un procedimiento, utiliza una variable global. No es necesario decir que es bastante difícil realizar un seguimiento y, en general, cada procedimiento puede hacer lo que quiera con cada variable global. Como era de esperar, las personas recurrieron a pasar argumentos y devolver valores de una manera diferente tan pronto como fue posible (a menos que fuera crítico para el rendimiento no hacerlo, por ejemplo, mire el código fuente de Build Engine (Duke 3D)). El odio a las variables globales nació aquí: tenía muy poca idea de qué parte del estado global leería y cambiaría cada procedimiento, y realmente no podía anidar las llamadas a procedimientos de forma segura.
¿Significa esto que el odio global variable es cosa del pasado? No exactamente.
Primero, debo mencionar que he visto exactamente el mismo enfoque para pasar argumentos en el proyecto en el que estoy trabajando en este momento. Para pasar dos instancias de tipo de referencia en C #, en un proyecto que tiene aproximadamente 10 años. Literalmente, no hay una buena razón para hacerlo de esta manera, y es muy probable que haya surgido de un desempaque de carga o de un completo malentendido sobre cómo funciona C #.
El punto más importante es que al agregar variables globales, está expandiendo el alcance de cada pieza de código que tiene acceso a esa variable global. ¿Recuerdas todas esas recomendaciones como "mantén tus métodos cortos"? Si tiene 600 variables globales (de nuevo, ejemplo del mundo real: /), todos los alcances de sus métodos se expanden implícitamente por esas 600 variables globales, y no hay una manera simple de realizar un seguimiento de quién tiene acceso a qué.
Si se hace mal (la forma habitual :)), las variables globales pueden tener acoplamiento entre sí. Pero no tiene idea de cómo se acoplan, y no existe un mecanismo para garantizar que el estado global siempre sea coherente. Incluso si introduce secciones críticas para tratar de mantener las cosas consistentes, encontrará que se compara mal con una base de datos ACID adecuada:
¿Es posible resolver estos problemas? Realmente no. Necesita encapsulación para manejar esto, o una disciplina realmente estricta. Es difícil hacer las cosas bien, y eso generalmente no es una muy buena receta para el éxito en el desarrollo de software :)
Un alcance más pequeño tiende a hacer que el código sea más fácil de razonar. Las variables globales hacen que incluso las piezas de código más simples incluyan grandes extensiones de alcance.
Por supuesto, esto no significa que el alcance global sea malo. Simplemente no debería ser la primera solución que elija, es un ejemplo típico de "simple de implementar, difícil de mantener".
fuente
Una variable global es una herramienta, puede usarse para bien y para mal.
Una base de datos es una herramienta, puede usarse para bien y para mal.
Como señala el póster original, la diferencia no es tan grande.
Los estudiantes sin experiencia a menudo piensan que los errores son algo que les sucede a otras personas. Los maestros usan "Las variables globales son malas" como una razón simplificada para penalizar el mal diseño. Los estudiantes generalmente no entienden que el hecho de que su programa de 100 líneas esté libre de errores no significa que se puedan usar los mismos métodos para los programas de 10000 líneas.
Cuando trabaja con bases de datos, no puede simplemente prohibir el estado global, ya que de eso se trata el programa. En su lugar, obtienes más pautas de detalles como ACID y Normal Forms, etc.
Si las personas usaran el enfoque ACID para las variables globales, no serían tan malas.
Por otro lado, si diseñas mal las bases de datos, pueden ser pesadillas.
fuente
Para mí, el mal principal es que los Globals no tienen protección contra los problemas de concurrencia. Puede agregar mecanismos para manejar tales problemas con Globals, pero encontrará que cuantos más problemas de concurrencia resuelva, más Globals comenzará a imitar una base de datos. El mal secundario no es un contrato de uso.
fuente
errno
en C.Algunas de las otras respuestas intentan explicar por qué es bueno usar una base de datos. ¡Están equivocados! Una base de datos es un estado global y, como tal, es tan malvada como un singleton o una variable global. ¡Es todo un error usar una base de datos cuando puedes usar fácilmente un Mapa local o una Matriz en su lugar!
Las variables globales permiten el acceso global, lo que conlleva el riesgo de abuso. Las variables globales también tienen ventajas. Generalmente se dice que las variables globales son algo que debes evitar, no algo que nunca deberías usar. Si puede evitarlos fácilmente, debe evitarlos. Pero si los beneficios superan los inconvenientes, ¡por supuesto, debería usarlos! *
Exactamente lo mismo ** se aplica a las bases de datos, que son de estado global, al igual que las variables globales. Si puede hacerlo sin acceder a una base de datos, y la lógica resultante hace todo lo que necesita y es igualmente complejo, el uso de una base de datos agrega un mayor riesgo a su proyecto, sin ningún beneficio correspondiente.
En la vida real, muchas aplicaciones requieren un estado global por diseño, a veces incluso un estado global persistente; por eso tenemos archivos, bases de datos, etc.
* La excepción aquí son los estudiantes. Tiene sentido prohibir a los estudiantes el uso de variables globales para que tengan que aprender cuáles son las alternativas.
** Algunas respuestas afirman incorrectamente que las bases de datos están de alguna manera mejor protegidas que otras formas de estado global (la pregunta es explícitamente sobre el estado global , no solo las variables globales). Eso es una mierda. La protección principal que se ofrece en el escenario de la base de datos es por convención, que es exactamente la misma para cualquier otro estado global. La mayoría de los idiomas también permiten una gran protección adicional para el estado global, en forma de
const
clases que simplemente no permiten cambiar su estado después de que se haya establecido en el constructor, o captadores y establecedores que pueden tener en cuenta la información de subprocesos o el estado del programa.fuente
En cierto sentido, la distinción entre variables globales y una base de datos es similar a la distinción entre miembros privados y públicos de un objeto (suponiendo que alguien todavía use campos públicos). Si piensa en todo el programa como un objeto, las variables globales son las variables privadas y la base de datos son los campos públicos.
La distinción clave aquí es de responsabilidad asumida.
Cuando escribe un objeto, se supone que cualquiera que mantenga los métodos de miembro se asegurará de que los campos privados se mantengan bien comportados. Pero ya renuncia a cualquier suposición sobre el estado de los campos públicos y los trata con mucho cuidado.
El mismo supuesto se aplica en un nivel más amplio a la base de datos global v / s. Además, el lenguaje de programación / ecosistema garantiza restricciones de acceso en privado v / s público en el mismo estado en que se aplica en la base de datos global (memoria no compartida) v / s.
Cuando entra en juego el subprocesamiento múltiple, el concepto de base de datos privada v / s pública v / s global v / s es simplemente distinciones a lo largo de un espectro.
fuente
Una base de datos puede ser un estado global, pero no tiene que serlo todo el tiempo. No estoy de acuerdo con la suposición de que no tienes control. Una forma de gestionar eso es el bloqueo y la seguridad. Esto se puede hacer en el registro, la tabla o la base de datos completa. Otro enfoque es tener algún tipo de campo de versión que evite el cambio de un registro si los datos están obsoletos.
Al igual que una variable global, los valores en una base de datos se pueden cambiar una vez que se desbloquean, pero hay muchas formas de controlar el acceso (no le dé a todos los desarrolladores la contraseña de la cuenta que tiene permiso para cambiar los datos). Si tiene una variable que tiene acceso limitado, no es muy global.
fuente
Hay varias diferencias:
El valor de una base de datos se puede modificar sobre la marcha. El valor de un global que se establece en el código, por otro lado, no se puede cambiar a menos que vuelva a implementar su aplicación y modifique su código. De hecho, esto es intencional. Una base de datos es para valores que pueden cambiar con el tiempo, pero las variables globales solo deben ser para cosas que nunca cambiarán y cuando no contienen datos reales.
Un valor de base de datos (fila, columna) tiene un contexto y un mapeo relacional en la base de datos. Esta relación se puede extraer y analizar fácilmente utilizando herramientas como Jailer (por ejemplo). Una variable global, por otro lado, es ligeramente diferente. Puede encontrar todos los usos, pero le sería imposible decirme todas las formas en que la variable interactúa con el resto de su mundo.
Las variables globales son más rápidas . Obtener algo de una base de datos requiere que se realice una conexión de base de datos, una selección para ejecutar y luego la conexión de la base de datos debe cerrarse. Cualquier tipo de conversiones que pueda necesitar se suman a eso. Compare eso con un acceso global en su código.
Estos son los únicos que puedo pensar en este momento, pero estoy seguro de que hay más. En pocas palabras, son dos cosas diferentes y deben usarse para diferentes objetivos .
fuente
Por supuesto, los globales no siempre son inapropiados. Existen porque tienen un uso legítimo. El principal problema con los globales, y la fuente principal de la advertencia para evitarlos, es que el código que usa un global está adjunto a ese único y global.
Por ejemplo, considere un servidor HTTP que almacena el nombre del servidor.
Si almacena el nombre del servidor en un archivo global, el proceso no puede ejecutar simultáneamente la lógica de dos nombres de servidor diferentes. Quizás el diseño original nunca contempló ejecutar más de una instancia de servidor a la vez, pero si luego decide que quiere hacerlo, simplemente no puede hacerlo si el nombre del servidor está en un global.
Por el contrario, si el nombre del servidor está en una base de datos, no hay problema. Simplemente puede crear una instancia de esa base de datos para cada instancia del servidor HTTP. Como cada instancia del servidor tiene su propia instancia de la base de datos, puede tener su propio nombre de servidor.
Entonces, la principal objeción a los globales, puede haber un solo valor para todo el código que accede a ese global, no se aplica a las entradas de la base de datos. El mismo código puede acceder fácilmente a instancias de bases de datos distintas que tienen valores diferentes para una entrada en particular.
fuente
Creo que esta es una pregunta interesante, pero es un poco difícil de responder porque hay dos cuestiones principales que se combinan bajo el término "estado global". El primero es el concepto de "acoplamiento global". La prueba de eso es que la alternativa dada para el estado global es la inyección de dependencia. La cuestión es que la DI no necesariamente elimina el estado global. Es decir, es absolutamente posible y común inyectar dependencias en el estado global. Lo que DI hace es eliminar el acoplamiento que viene con las variables globales y el patrón Singleton comúnmente utilizado. Aparte de un diseño un poco menos obvio, hay muy pocos inconvenientes para eliminar este tipo de acoplamiento y los beneficios de eliminar el acoplamiento aumenta exponencialmente con el número de dependencias de esos globales.
El otro aspecto de esto es el estado compartido. No estoy seguro de si existe una distinción realmente clara entre el estado globalmente compartido y el estado compartido en general, pero los costos y beneficios son mucho más matizados. En pocas palabras, hay innumerables sistemas de software que requieren un estado compartido para ser útiles. Bitcoin, por ejemplo, es una forma muy inteligente de compartir el estado globalmente (literalmente) de manera descentralizada. Compartir el estado mutable correctamente sin crear grandes cuellos de botella es difícil pero útil. Entonces, si realmente no necesita hacerlo, puede simplificar su aplicación minimizando el estado mutable compartido.
Entonces, la cuestión de cómo las bases de datos difieren de las globales también se bifurca en estos dos aspectos. ¿Introducen el acoplamiento? Sí, pueden, pero depende mucho de cómo está diseñada la aplicación y cómo está diseñada la base de datos. Hay demasiados factores para tener una respuesta única sobre si las bases de datos introducen el acoplamiento global sin detalles del diseño. En cuanto a si introducen el intercambio de estado, bueno, ese es el punto principal de una base de datos. La pregunta es si lo hacen bien. Nuevamente, creo que esto es demasiado complicado de responder sin mucha otra información, como las alternativas y muchas otras compensaciones.
fuente
Lo pensaría de manera ligeramente diferente: el comportamiento de "variable global" es un precio pagado por los administradores de bases de datos (DBA) porque es un mal necesario para hacer su trabajo.
El problema con las variables globales, como han señalado varios otros, no es arbitrario. El problema es que su uso hace que el comportamiento de su programa sea cada vez menos predecible porque se hace más difícil determinar quién está usando la variable y de qué manera. Este es un gran problema para el software moderno, porque normalmente se le pide al software moderno que haga muchas cosas flexibles. Puede hacer miles de millones o incluso billones de manipulaciones complejas del estado durante el transcurso de una carrera. La capacidad de demostrar declaraciones verdaderas sobre lo que hará ese software en esos miles de millones o trillones de operaciones es extremadamente valiosa.
En el caso del software moderno, todos nuestros idiomas proporcionan herramientas para ayudar en esto, como la encapsulación. La elección de no usarlo es innecesaria, lo que lleva a la mentalidad de "los globales son malvados". En muchas regiones del campo de desarrollo de software, las únicas personas que los usan son personas que no saben codificar mejor. Esto significa que no solo son problemas directamente, sino que indirectamente sugieren que el desarrollador no sabía lo que estaban haciendo. En otras regiones, encontrará que los globales son totalmente normales (el software incorporado, en particular, ama los globales, en parte porque funcionan bien con los ISR). Sin embargo, en medio de los muchos desarrolladores de software que existen, son la voz minoritaria, por lo que la única voz que escuchas son "los globales son malvados".
El desarrollo de bases de datos es una de esas situaciones de voz minoritarias. Las herramientas necesarias para hacer el trabajo DBA son muy poderosas, y su teoría no se basa en la encapsulación. Para buscar cada instante de rendimiento de sus bases de datos, necesitan un acceso ilimitado a todo, similar a los globales. Maneje una de sus monstruosas bases de datos de 100 millones de filas (¡o más!), Y apreciará por qué no permiten que su motor DB contenga ningún golpe.
Pagan un precio por eso, un precio muy alto. Los DBA se ven obligados a ser casi patológicos con su atención al detalle, porque sus herramientas no los protegen. Lo mejor que tienen en cuanto a protección es ACID o quizás claves externas. Aquellos que no son patológicos se encuentran con un completo desastre de tablas que es completamente inutilizable, o incluso corrupto.
No es raro tener paquetes de software de 100k líneas. En teoría, cualquier línea en el software puede afectar a cualquier global en cualquier momento. En los DBA, nunca encontrará 100k consultas diferentes que puedan modificar la base de datos. Sería poco razonable mantenerlo con la atención a los detalles necesarios para protegerte de ti mismo. Si un DBA tiene algo grande como eso, encapsulará intencionalmente su base de datos utilizando accesores, esquivando los problemas "globales" y luego hará todo el trabajo posible a través de ese mecanismo "más seguro". Por lo tanto, cuando se trata de empujar, incluso las personas de la base de datos evitan los globales. Simplemente vienen con mucho peligro, y hay alternativas que son tan fuertes, pero no tan peligrosas.
¿Preferirías caminar sobre vidrios rotos o sobre aceras bien barridas, si todas las demás cosas son iguales? Sí, puedes caminar sobre cristales rotos. Sí, algunas personas incluso se ganan la vida haciéndolo. Pero aún así, ¡déjelos barrer la acera y seguir adelante!
fuente
Creo que la premisa es falsa. No hay razón para que una base de datos deba ser "estado global" en lugar de un objeto de contexto (muy grande). Si está vinculado a la base de datos particular que su código está utilizando a través de variables globales o parámetros de conexión de base de datos global fijos, no es diferente, y no menos malo, que cualquier otro estado global. Por otro lado, si pasa correctamente un objeto de contexto para la conexión de la base de datos, es solo un estado contextual grande (y ampliamente utilizado), no un estado global.
Medir la diferencia es fácil: ¿podría ejecutar dos instancias de la lógica de su programa, cada una utilizando su propia base de datos, en un solo programa / proceso sin realizar cambios invasivos en el código? Si es así, su base de datos no es realmente "estado global".
fuente
Los globales no son malvados; Son simplemente una herramienta. El MAL USO de los globales es problemático, como lo es el mal uso de cualquier otra característica de programación.
Mi recomendación general es que los globales solo deben usarse en situaciones que se entienden y piensan bien, donde otras soluciones son menos óptimas. Lo más importante es que desea asegurarse de haber documentado bien dónde podría modificarse ese valor global, y si está ejecutando multiproceso, se está asegurando de que el acceso global y los globales dependientes sean dependientes de manera transaccional.
fuente
Patrón de solo lectura y suponga que sus datos no están actualizados cuando los imprime. Cola escribe o maneja conflictos de otra manera. Bienvenido al infierno demonio, estás usando db global.
fuente