¿En qué se diferencian los globales de una base de datos?

247

Acabo de encontrar esta vieja pregunta preguntando qué es tan malo sobre el estado global, y la respuesta más votada y aceptada afirma que no puede confiar en ningún código que funcione con variables globales, ya que podría aparecer algún otro código en otro lugar, modificar su valor y luego no lo sabe ¡cuál será el comportamiento de su código porque los datos son diferentes! Pero cuando lo veo, no puedo dejar de pensar que esa es una explicación muy débil, ya que no es tan diferente 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 lo que son los datos; ese es todo el punto Todo lo que importa es que su código trate correctamente con los datos que encuentra. (Obviamente, estoy ocultando el tema del almacenamiento en caché a menudo espinoso, pero ignoremos eso por el momento).

Pero si los datos con los que está trabajando provienen de una fuente externa sobre la que su código no tiene control, como una base de datos (o entrada de usuario, un socket de red, un archivo, etc.) y no hay nada de malo en eso, entonces, ¿cómo son los datos globales dentro del código en sí, sobre el cual su programa tiene un mayor grado de control? De alguna manera es algo malo cuando obviamente es mucho menos malo que las cosas perfectamente normales que nadie ve como un problema?

    
pregunta Mason Wheeler 24.05.2016 - 21:42

22 respuestas

117

Primero, diría que la respuesta que vincula para sobreestimar ese problema 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 problema aún más, hay diferencias entre el estado global en una aplicación típica orientada a objetos y el estado que se mantiene en una base de datos. Brevemente, los más importantes de estos 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 modificar comportamiento , no solo data.

  • El estado global en una aplicación generalmente no proporciona la consistencia sólida de las garantías que brinda una base de datos; no hay transacciones durante las cuales usted vea un estado consistente, no haya 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 tan malos, podemos eliminar algunos de los problemas potenciales y una solución parcial es mejor que ninguna solución.

    
respondido por el Jules 24.05.2016 - 22:05
75

Primero, ¿cuáles son los problemas con las variables globales, según la respuesta aceptada a la pregunta que vinculó?

  

Muy brevemente, hace que el estado del programa sea impredecible.

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 no confiable.

  

Además, el estado global daña la legibilidad de su código.

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 al código que está leyendo (o debería ser).

Los controladores de base de datos suelen proporcionar una interfaz coherente y comprensible para acceder a datos que son iguales 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 varios subprocesos o métodos pueden operar en la misma pieza de datos sin atomicidad, a menos que agregue la sincronización. Las actualizaciones de los datos son impredecibles y difíciles de rastrear. Las actualizaciones se pueden intercalar, lo que puede causar ejemplos de libros de texto con muchos problemas de corrupción de datos multiproceso (por ejemplo, incrementos intercalados).

Las bases de datos normalmente modelan datos diferentes de las variables globales para comenzar, 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 mitiga muchas de las preocupaciones con las variables globales.

    
respondido por el user22815 24.05.2016 - 22:11
44

Ofrecería algunas observaciones:

Sí, una base de datos es un estado global.

De hecho, es un estado super-global, como usted señaló. Es universal! Su alcance implica cualquier cosa o cualquiera que se conecte a la base de datos. Y, sospecho que muchas personas con años de experiencia pueden contarle 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 consecuencias potenciales de usar una variable global es que dos "módulos" distintos usarán esa variable para sus propios propósitos 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 de manera extrínseca de alguna manera, no hace nada.

Un módulo útil puede ser dado datos o puede encontrar . Y puede devolver datos o puede modificar estado. Pero, si no interactúa con el mundo externo de alguna manera, puede que no haga nada.

Ahora, nuestra preferencia es recibir datos y devolver . 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 las 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, al final del día, evitar que estas operaciones entren en conflicto entre sí en principio , simplemente implica pensar con cuidado. (y cometer errores ...)

Pero también, generalmente no estamos trabajando directamente con el estado global.

A menos que la aplicación se encuentre en la capa de datos (en SQL o lo que sea), los objetos con los que trabajan nuestros módulos son en realidad un copias del estado global compartido. Podemos hacer lo que queramos sin afectar al estado real y 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 locales globales.

Y, por último, generalmente hacemos cosas diferentes con las bases de datos de las que podríamos con globales traviesos.

Un aspecto global travieso y roto como este:

Int32 counter = 0;

public someMethod() {
  for (counter = 0; counter < whatever; counter++) {
    // do other stuff.
  }
}

public otherMethod() {
  for (counter = 100; counter < whatever; counter--) {
    // do other stuff.
  }
}

Simplemente no usamos bases de datos para cosas en proceso / operativas como esa. 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 lenta e incómoda interacción con las bases de datos simplemente los convierte en malos candidatos para muchos de los errores que históricamente hemos cometido. hecho con variables.

    
respondido por el svidgen 25.05.2016 - 00:57
21

No estoy de acuerdo con la afirmación fundamental de que:

  

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, en este caso.

Mi pensamiento inicial fue "Wow. Simplemente Wow". Se gasta tanto tiempo y esfuerzo tratando de evitar exactamente esto, y resolviendo qué compromisos y compromisos funcionan para cada aplicación. Solo ignorarlo es una receta para el desastre.

Pero también yo di despierto 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 de usar una base de datos, debe tener un identificador (a menos que lo almacene en una variable global ...)

Por ejemplo, usar una variable global puede tener este aspecto

int looks_ok_but_isnt() {
  return global_int++;
}

int somewhere_else() {
  ...
  int v = looks_ok_but_isnt();
  ...
}

Pero hacer lo mismo con una base de datos tendría que ser más explícito sobre lo que está haciendo

int looks_like_its_using_a_database( MyDB * db ) {
   return db->get_and_increment("v");
}

int somewhere_else( MyBD * db ) { 
   ...
   v = looks_like_its_using_a_database(db);
   ...
}

La base de datos, obviamente, se está mezclando con una base de datos. Si no quería usar una base de datos, puede usar el estado explícito y se ve casi igual que el caso de la base de datos.

int looks_like_it_uses_explicit_state( MyState * state ) {
   return state->v++;
}


int somewhere_else( MyState * state ) { 
   ...
   v = looks_like_it_uses_explicit_state(state);
   ...
}

Por lo tanto, argumentaría que usar una base de datos es mucho más como usar un estado explícito, que usar variables globales.

    
respondido por el Michael Anderson 25.05.2016 - 03:10
18

El punto en el que no se puede confiar en la única razón por la que no se puede confiar en las variables globales ya que el estado puede cambiarse en otro lugar es, en sí mismo, no es una razón suficiente para no usarlas, pero está de acuerdo (¡es una buena razón!). Es probable que la respuesta fuera principalmente describiendo el uso donde restringir el acceso de una variable a solo las áreas de código que le interesan tendría más sentido.

Sin embargo, las bases de datos son una cuestión diferente, ya que están diseñadas para ser accedidas "globalmente", por así decirlo.

Por ejemplo:

  • Las bases de datos normalmente tienen una validación de tipo y estructura integrada que va más allá del idioma que accede a ellas.
  • Las bases de datos actualizan casi por unanimidad las transacciones basadas en transacciones, lo que evita estados inconsistentes, donde no hay garantías de cómo se verá el estado final en un objeto global (a menos que esté oculto detrás de un singleton)
  • La estructura de la base de datos se documenta, al menos implícitamente, en una estructura fuera de la tabla o del objeto, más que la aplicación que la utiliza

Lo más importante es que las bases de datos tienen un propósito diferente al de una variable global. Las bases de datos son para almacenar y buscar grandes cantidades de datos organizados, donde las variables globales sirven nichos específicos (cuando están justificados).

    
respondido por el Jeffrey Sweeney 24.05.2016 - 22:03
10
  

Pero cuando lo veo, no puedo evitar pensar que esa es una explicación muy débil, porque ¿en qué se diferencia del trabajo con datos almacenados en una base de datos?

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. Así que 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 sin protección. La lectura desde un teclado es muy obvia y protegida. 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 su ejemplo, las bases de datos. Es obvio para el lector el código que esta función lee desde el teclado, esa función accede a un archivo, otra función accede a la memoria compartida (y es mejor que haya protecciones alrededor de eso), y otras funciones acceden a una base de datos.

Por otro lado, con las variables globales no es nada obvio. La API dice que llamar a foo(this_argument, that_argument) . No hay nada en la secuencia de llamada que indique que la variable global g_DangerWillRobinson debe configurarse en algún valor pero antes de llamar a foo (o examinarse después de llamar a foo ).

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 ese foo toma una referencia no constante como argumento . (Compare con C #, que establece que tanto la definición de la función como el sitio de la llamada deben calificar un parámetro de referencia con la palabra clave ref ). Si bien no estoy de acuerdo con el estándar de Google en 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 ocultas de comunicaciones son muy malas karma. La referencia no constante de C ++ representa una línea de comunicación menor oculta. Una buena API o un buen IDE me mostrarán que "¡Oh! Esto es una llamada por referencia". Las variables globales son una gran línea de comunicación oculta.

    
respondido por el David Hammen 25.05.2016 - 01:24
8

Creo que la explicación citada simplifica en exceso el problema 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ómo su programa depende del estado global (mutable). Si una función de biblioteca para dividir cadenas en espacios en blanco dependería de los resultados intermedios almacenados en una base de datos, objetaría este diseño al menos tanto como objetarí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 punto y que sí lo hará una estructura global de clave-valor en la memoria, esto no es necesariamente un signo de diseño deficiente. Lo que es importante es que, independientemente de la solución que elija para almacenar sus datos, esta opción está aislada en una parte muy pequeña del sistema, por lo que la mayoría de los componentes pueden ser ajenos a la solución elegida para la implementación y probada por unidades de forma aislada. La solución se puede cambiar más adelante con poco esfuerzo.

    
respondido por el 5gon12eder 24.05.2016 - 22:19
8

Como ingeniero de software que trabaja predominantemente con firmware incorporado, casi siempre uso variables globales para cualquier cosa que vaya entre los módulos. De hecho, es la mejor práctica para incrustado. Se asignan de forma estática, por lo que no hay riesgo de volcar el montón / pila y no se necesita más tiempo para la asignación / limpieza de la pila en la entrada / salida de la función.

La desventaja de esto es que do tenemos que considerar cómo se usan esas variables, y mucho de eso se reduce al mismo tipo de pensamiento que se utiliza en la negociación de bases de datos. Cualquier lectura / escritura asíncrona de las variables DEBE debe ser atómica. Si más de un lugar puede escribir una variable, debe pensarse en asegurarse de que siempre escriban datos válidos, de modo que la escritura anterior no se reemplace arbitrariamente (o que el reemplazo arbitrario sea algo seguro). Si se lee la misma variable más de una vez, se debe pensar en qué pasará si la variable cambia de valor entre las lecturas, o se debe tomar una copia de la variable al comienzo 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 contrato trabajando en un sistema de contramedidas para aeronaves, tan relacionado con la seguridad, el equipo de software estaba buscando un informe de errores que habían estado tratando de resolver durante una semana O así. Tuve el tiempo justo para descargar las herramientas de desarrollo y una copia del código. Pregunté "¿no se podría actualizar esa variable entre las lecturas y causarla?" pero realmente no obtuve una respuesta. Oye, Después de todo, ¿qué sabe el chico nuevo? Así que mientras aún estaban discutiéndolo, agregué un código de protección para leer la variable de forma atómica, hice una compilación local y básicamente dije "hey chicos, intenten esto". Forma de demostrar que valía la pena Mi tarifa de contratación. :)

Por lo tanto, las variables globales no son una cosa inequívocamente mala, pero te dejan abierto a una amplia gama de problemas si no piensas en ellas con cuidado.

    
respondido por el Graham 25.05.2016 - 16:39
7

Dependiendo de qué aspecto esté juzgando, las variables globales y el acceso a la base de datos pueden ser mundos distintos, pero mientras los juzgamos 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 puede considerarse pura, ya que, para el mismo conjunto o argumentos, puede producir diferentes salidas 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 una parte tan importante de la interfaz de la función como sus otros argumentos, por lo que no es el problema. El problema es que solo está oculto hasta el momento en que estamos sorprendidos por el comportamiento inesperado de las funciones aparentemente obvias, Luego, lea sus implementaciones para descubrir las dependencias ocultas .

Esta parte, el momento en que una variable global se convierte en una dependencia oculta es lo que los programadores consideran 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, sobre todo, aumenta el tiempo de corrección y corrección de errores 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 las consultas y comandos de la base de datos, ocultando estas dependencias y causándonos el mismo problema que causan las variables globales; o podemos hacerlos explícitos, lo que, según resulta, se considera una práctica recomendada que incluye muchos nombres, como el patrón de repositorio, el almacén de datos, la puerta de enlace, etc.

P.S .: Hay otros aspectos que son importantes para esta comparación, como si se trata de concurrencia, pero este punto está cubierto por otras respuestas aquí.

    
respondido por el MichelHenrich 25.05.2016 - 04:20
6

Bien, comencemos desde el punto histórico.

Estamos en una aplicación antigua, escrita en su mezcla 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 hace falta decir que esto es bastante difícil de seguir y, en general, cada procedimiento puede hacer lo que quiera con cada variable global. Como era de esperar, las personas pasaron a pasar argumentos y valores de retorno de una forma diferente tan pronto como fue posible (a menos que fuera crítico para el rendimiento, por ejemplo, ver el código fuente del Build Engine (Duke 3D)). El odio de las variables globales nació aquí: tenías muy poca idea de qué parte del estado global se leería y cambiaría cada procedimiento, y realmente no podrías anidar las llamadas a procedimientos de manera segura.

¿Esto significa que el odio de la variable global es una cosa del pasado? No del todo.

Primero, debo mencionar que he visto exactamente el mismo enfoque para aprobar argumentos en el proyecto en el que estoy trabajando ahora mismo. Para pasar dos instancias de tipo de referencia en C #, en un proyecto que tiene aproximadamente 10 años de antigüedad. Literalmente, no hay una buena razón para hacerlo de esta manera, y lo más probable es que haya nacido a partir de un cultivo de carga o de un malentendido completo de 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 (nuevamente, ejemplo del mundo real: /), todos los ámbitos de sus métodos se expanden implícitamente por esas 600 variables globales, y no hay una forma sencilla de saber quién tiene acceso a qué.

Si se hace mal (de la forma habitual :)), las variables globales pueden tener un acoplamiento entre sí. Pero no tiene idea de cómo están acoplados, y no hay ningún mecanismo para garantizar que el estado global sea siempre coherente. Incluso si introduce secciones críticas para tratar de mantener las cosas coherentes, encontrará que se compara mal con una base de datos ACID adecuada:

  • No hay forma de revertir una actualización parcial, a menos que se conserven los valores anteriores antes de la "transacción". No hace falta decir que, en este punto, pasar un valor como argumento ya es una victoria :)
  • Todos los que accedan al mismo estado deben cumplir con el mismo proceso de sincronización. Pero no hay manera de hacer cumplir esto: si olvida configurar la sección crítica, está jodido.
  • Incluso si sincroniza correctamente todos los accesos, puede haber llamadas anidadas que accedan al estado parcialmente modificado. Esto significa que usted puede interrumpir el bloqueo (si sus secciones críticas no son relevantes), o lidiar con datos inconsistentes (si son relevantes).

¿Es posible resolver estos problemas? Realmente no. Necesitas encapsulación para manejar esto, o una disciplina realmente estricta. Es difícil hacer las cosas bien, y esa generalmente no es una muy buena receta para el éxito en el desarrollo de software :)

El 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 más simples de código incluyan enormes franjas de alcance.

Por supuesto, esto no significa que el alcance global sea malo. Es solo que no debería ser la primera solución que elija, es un ejemplo típico de "fácil de implementar, difícil de mantener".

    
respondido por el Luaan 25.05.2016 - 10:02
6

Una variable global es una herramienta, se puede usar para bien y para mal.

Una base de datos es una herramienta, se puede usar 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. En general, los estudiantes 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 trabajas con bases de datos, no puedes simplemente prohibir el estado global, ya que de eso se trata el programa. En su lugar, obtienes más detalles de pautas como ACID y Formas normales, 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.

    
respondido por el Stig Hemmer 25.05.2016 - 12:33
5

Para mí, el principal mal es que los Globales no tienen protección contra problemas de concurrencia. Puede agregar mecanismos para manejar estos problemas con Globals, pero encontrará que cuantos más problemas de concurrencia resuelva, más comenzarán a imitar sus bases de datos. El mal secundario no es un contrato de uso.

    
respondido por el G DeMasters 25.05.2016 - 03:28
5

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 incorrecto 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 debe evitar, no algo que nunca debe usar. Si puedes evitarlos fácilmente debes evitarlos. Pero si los beneficios superan los inconvenientes, ¡por supuesto que deberías usarlos! *

Lo mismo ** se aplica exactamente a las bases de datos, que son de estado global, al igual que las variables globales. Si puede hacerlo sin tener que acceder a una base de datos, y la lógica resultante hace todo lo que necesita y es igualmente compleja, el uso de una base de datos aumenta el riesgo de 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 que usen variables globales para que tengan que aprender cuáles son las alternativas.

** Algunas respuestas afirman incorrectamente que las bases de datos están mejor protegidas que otras formas de estado global (la pregunta es explícitamente acerca de estado global , no solo de variables globales). Eso es bollocks. La protección principal ofrecida 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 cantidad de 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 que obtengan y establezcan la información de subprocesos o el estado del programa. en cuenta.

    
respondido por el Peter 26.05.2016 - 20:47
2

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, entonces las variables globales son las variables privadas y la base de datos son los campos públicos.

La distinción clave aquí es una de responsabilidad asumida.

Cuando escribe un objeto, se asume que cualquiera que mantenga los métodos miembros se asegurará de que los campos privados se mantengan bien. Pero ya abandonas cualquier suposición sobre el estado de los campos públicos y los tratas con mucho cuidado.

El mismo supuesto se aplica a un nivel más amplio a la base de datos v / s de globals. Además, el lenguaje de programación / ecosistema garantiza las restricciones de acceso a las v / s públicas en la misma base de datos que las impone en la base de datos v / s globals (memoria no compartida).

Cuando el subprocesamiento múltiple entra en juego, el concepto de v / s privado v / s global v / s base de datos es simplemente distinciones a lo largo de un espectro.

static int global; // within process memory space
static int dbvar; // mirrors/caches data outside process memory space

class Cls {
    public: static int class_public; // essentially the same as global
    private: static int class_private; // but public to all methods in class

    private: static void method() {
        static int method_private; // but public to all scopes in method
        // ...
        {
            static int scope1_private; // mutex guarded
            int the_only_truly_private_data;
        }
        // ...
        {
            static int scope2_private; // mutex guarded
        }
    }
}
    
respondido por el Benito Ciaro 30.05.2016 - 02:04
1

Una base de datos puede ser un estado global, pero no tiene que ser todo el tiempo. No estoy de acuerdo con la suposición de que usted no tiene control. Una forma de gestionar eso es el bloqueo y la seguridad. Esto se puede hacer en el registro, tabla o base de datos completa. Otro enfoque es tener algún tipo de campo de versión que impida 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é la contraseña a todos los desarrolladores a la cuenta permitida para cambiar datos .). Si tiene una variable que tiene acceso limitado, no es muy global.

    
respondido por el JeffO 25.05.2016 - 15:25
0

Hay varias diferencias:

  • Un valor de base de datos puede modificarse sobre la marcha. El valor de un global que se establece en el código, por otra parte, 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 deben solo ser para cosas que nunca cambiarán y cuando no contengan datos reales.

  • Un valor de base de datos (fila, columna) tiene un contexto y una asignación relacional en la base de datos. Esta relación se puede extraer y analizar fácilmente usando 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 todos 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 a la base de datos, que se ejecute una selección para mí y luego se cierre la conexión a la base de datos. Cualquier tipo de conversiones que pueda necesitar son superiores a eso. Compare eso con un acceso global en su código.

Estos son los únicos en los 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 .

    
respondido por el Arnab Datta 25.05.2016 - 14:35
0

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 admonición para evitarlos, es que el código que usa un global está adjunto a ese único global.

Por ejemplo, considere un servidor HTTP que almacena el nombre del servidor.

Si almacena el nombre del servidor en un global, el proceso no puede ejecutar simultáneamente la lógica para dos nombres de servidor diferentes. Tal vez el diseño original nunca contempló ejecutar más de una instancia de servidor a la vez, pero si más tarde decide que quiere hacer eso, simplemente no puede hacerlo si el nombre del servidor está en forma 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. Debido a que cada instancia del servidor tiene su propia instancia de la base de datos, puede tener su propio nombre de servidor.

Por lo tanto, la objeción principal a los globales, solo puede haber un 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 distintas instancias de base de datos que tienen valores diferentes para una entrada en particular.

    
respondido por el David Schwartz 26.05.2016 - 12:20
0

Creo que esta es una pregunta interesante, pero es un poco difícil de responder porque hay dos problemas principales que se combinan bajo el término 'estado global'. El primero es el concepto de 'acoplamiento global'. La prueba de ello es que la alternativa dada para el estado global es la inyección de dependencia. Lo que pasa es que la DI no elimina necesariamente el estado global. Es decir, es absolutamente posible y común inyectar dependencias en el estado global. Lo que hace DI es eliminar el acoplamiento que viene con las variables globales y el patrón Singleton que se usa comúnmente. Aparte de un diseño ligeramente menos obvio, hay un pequeño inconveniente en la eliminación de este tipo de acoplamiento y los beneficios de eliminar el acoplamiento aumentan exponencialmente con el número de dependencias de esos globales.

El otro aspecto de esto es el estado compartido. No estoy seguro de si hay una distinción realmente clara entre el estado compartido globalmente 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 una manera descentralizada. Compartir el estado mutable correctamente sin crear grandes cuellos de botella es difícil pero útil. Por lo tanto, si realmente no necesita hacerlo, puede simplificar su aplicación minimizando el estado mutable compartido.

Por lo tanto, la pregunta de cómo las bases de datos difieren de las globales está también dividida en estos dos aspectos. ¿Introducen acoplamiento? Sí, pueden pero depende mucho de cómo se diseñe la aplicación y de la base de datos. Hay demasiados factores para tener una respuesta única a si las bases de datos introducen un acoplamiento global sin detalles del diseño. En cuanto a si introducen compartir el estado, bueno, ese es el punto principal de una base de datos. La pregunta es si lo hacen bien. Una vez más, creo que esto es demasiado complicado para responder sin una gran cantidad de información adicional como las alternativas y muchas otras compensaciones.

    
respondido por el JimmyJames 27.05.2016 - 19:24
0

Lo pensaría de manera ligeramente diferente: el comportamiento similar a "variable global" es un precio que pagan 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 otros, no es arbitrario. El problema es que su uso hace que el comportamiento de su programa sea cada vez menos predecible porque se vuelve más difícil determinar quién está usando la variable y de qué manera. Este es un gran problema para el software moderno, ya que generalmente se le pide al software moderno que haga muchas cosas flexibles. Puede hacer miles de millones o incluso billones de complejas manipulaciones estatales durante el curso de una carrera. La capacidad de demostrar afirmaciones verdaderas sobre lo que hará el software en esos miles de millones o billones 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 que "los mundos son malos". En muchas regiones del campo de desarrollo de software, las únicas personas que los usan son personas que no saben cómo 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 integrado, en particular, ama los globales, en parte porque funcionan bien con los ISR). Sin embargo, entre los muchos desarrolladores de software que hay por ahí, son la voz de la minoría, por lo que la única voz que escuchas es que "los globales son malos".

El desarrollo de la base de datos es una de esas situaciones de voz minoritaria. Las herramientas necesarias para realizar el trabajo de DBA son muy poderosas, y su teoría no está arraigada en la encapsulación. Para obtener todos los beneficios del rendimiento de sus bases de datos, necesitan acceso completo y sin restricciones a todo, de forma similar a los globales. Utilice una de sus monstruosas bases de datos de 100 millones de filas (¡o más!), Y apreciará por qué no dejan que su motor de base de datos contenga ningún golpe.

Ellos pagan un precio por eso, un precio caro. Los DBA se ven obligados a ser casi patológicos con su atención a los detalles, 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 mess completo de tablas que son completamente inutilizables, o incluso corruptas.

No es raro tener paquetes de software de 100k line. En teoría, cualquier línea en el software puede afectar a cualquier global en cualquier momento. En los DBA, nunca encuentras 100k consultas diferentes que puedan modificar la base de datos. Eso sería irrazonable de mantener con la atención a los detalles necesarios para protegerte de ti mismo. Si un DBA tiene algo tan grande como eso, intencionalmente encapsularán su base de datos usando accesores, evitando los problemas "globales", y luego harán todo el trabajo que puedan a través de ese mecanismo "más seguro". Por lo tanto, cuando se produce un empuje, incluso las personas de la base de datos evitan los globales. Simplemente vienen con mucho peligro, y hay alternativas que son simplemente tan fuertes, pero no tan peligrosas.

¿Prefieres caminar alrededor de vidrios rotos o en aceras bien barridas, si todas las otras cosas son iguales? Sí, puedes caminar sobre vidrios rotos. Sí, algunas personas incluso se ganan la vida haciéndolo. Pero aún así, ¡simplemente déjalos barrer la acera y seguir adelante!

    
respondido por el Cort Ammon 28.05.2016 - 05:14
0

Creo que la premisa es falsa. No hay razón para que una base de datos tenga que ser "estado global" en lugar de un objeto de contexto (muy grande). Si se está vinculando a la base de datos en particular que utiliza su código a través de variables globales o de parámetros fijos de conexión a la base de datos global, no es diferente ni menos malvado 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 simplemente 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".

    
respondido por el R.. 30.05.2016 - 04:13
-2

Los globales no son malos; son simplemente una herramienta. El uso inadecuado de los dispositivos globales es problemático, al igual que el uso indebido de cualquier otra función de programación.

Mi recomendación general es que los globales solo se deben usar en situaciones que se entienden bien y están pensadas, donde otras soluciones son menos óptimas. Lo más importante es que quiere asegurarse de haber documentado bien dónde se puede modificar ese valor global y, si está ejecutando multiproceso, está asegurándose de que los globales y los globales co-dependientes tengan acceso de una manera que sea transaccional.

    
respondido por el Byron Jones 25.05.2016 - 20:19
-2

Patrón de solo lectura, y suponga que sus datos no están actualizados cuando los imprima. La cola escribe o maneja los conflictos de otra manera. Bienvenido al infierno diablo, estás usando db global.

    
respondido por el Vince 31.05.2016 - 23:52

Lea otras preguntas en las etiquetas

Comentarios Recientes

Nuevamente: ¿todos los atributos de la base de datos son primitivos? No, estamos usando una clase para manejar automáticamente los atributos de almacenamiento. En teoría, el modelo no necesita hacer nada más que observar a los usuarios que presionan enter en ubicaciones y presionan enter en cosas como gatos o maullidos. Del mismo modo, los enlaces deben mantenerse para establecer sus propiedades si el usuario presiona enter en cualquiera de ellos, nuevamente, eso es algo que no puede hacer nada más que estar atento... Lee mas