2010-03-31 18 views
46

Esto es ciertamente una pregunta bastante flexible. Mi comprensión actual de singletons es que son una clase que configuras de tal forma que solo se crea una instancia.Propósito de los singletons en la programación

Esto suena como una clase estática para mí. La principal diferencia es que con una clase estática no puedes/no puedes instanciarla, solo la usas como Math.pi(). Con una clase Singleton, todavía tendría que hacer algo como

singleton mySingleton = new singleton(); 
mysingleton.set_name("foo"); 
singleton otherSingleton = new singleton(); 
// correct me if i am wrong, but mysingleton == othersingleton right now, yes? 
// this the following should happen? 
otherSingleston.set_name("bar"); 
mysingleton.report_name(); // will output "bar" won't it? 

Tenga en cuenta, estoy pidiendo este idioma de forma independiente, más sobre el concepto. Así que no estoy preocupado acerca de cómo codificar una clase así, sino más bien por qué querrías hacerlo y qué cosas tendrías que considerar.

+1

Mucha gente ha dicho que los singletons son básicamente solo una forma de obtener variables globales, y esto es 'malo'. Pero seguramente hay momentos en que las variables globales son útiles? ¿Cómo es que las variables globales de singletons? – thecoshman

Respuesta

49

La principal ventaja de un singleton sobre una clase que consiste en estática es que luego puede decidir fácilmente que realmente necesita más de una instancia, p. uno por hilo

Sin embargo, en la práctica, el objetivo principal de singletons es hacer que las personas se sientan menos mal por tener variables globales.

Un ejemplo práctico para buen uso de de un singleton: tiene una aplicación que utiliza una base de datos SQL y necesita un grupo de conexiones. El objetivo de dicho grupo es reutilizar la conexión de base de datos, por lo que definitivamente desea que todos los clientes utilicen el mismo grupo. Por lo tanto, tenerlo como singleton es el diseño correcto. Pero un día necesita la aplicación para conectarse a un segundo servidor de bases de datos, y darse cuenta de que no puede tener conexiones con diferentes servidores en el mismo grupo. Por lo tanto, su singleton "instancia única general" se convierte en "una instancia por servidor de base de datos".

+38

* LOL * +1 para "Singletons son el nombre correcto para las variables globales en OO" ;-) –

+0

Así que es un singleton "propiamente formado" una especie de casa de medio camino entre una clase normal que puedes aplicar tantas veces como quieres tantos hilos como una clase estática que solo puede ser, a falta de una mejor palabra, instanciada una vez ... en todos tus hilos? Nunca se trató con aplicaciones de múltiples hilos. Entonces, ¿existen clases estáticas en el mismo estado, incluso sobre múltiples hilos? – thecoshman

+0

@thecoshman: el asunto "uno por hilo" era solo un ejemplo, podría ser un criterio diferente como "cada 100 llamada recibe una nueva instancia". Pero sí, una clase estática sería la misma en todos los hilos, si su entorno tiene multiprocesamiento de memoria compartida. –

-1

No todos los idiomas tienen "clases estáticas" (por ejemplo C++ no los tiene).

De nuevo con el ejemplo de C++, agregar variables estáticas a una clase es un problema porque necesita ponerlas tanto en el encabezado como en el archivo .cpp, por lo que un singleton en ese caso es muy útil.

Cada idioma es diferente. Supongo que en C# no son muy útiles (y de hecho, por lo que sé, no se usan con mucha frecuencia)

+1

C++ permite funciones miembro estáticas y, por lo tanto, admite clases estáticas (que, en términos generales, no son más que clases con funciones miembro estáticas solamente). –

+0

Hace un tiempo desde que jugué con C++ de esa manera. No me di cuenta de que la estática era tan 'limitada'. ¿No tienes cosas como las clases de matemáticas que ya puedes usar? o ya se han inicializado en las bibliotecas? – thecoshman

+0

@Marcelo: por 'clases estáticas' Quise decir algo así como la palabra clave estática en C#. –

2

Los singleton son más útiles cuando se quiere una interfaz para un servicio singleton, pero no se sabe hasta el tiempo de ejecución, qué clase concreta será instanciada.

Por ejemplo, es posible que desee declarar un servicio de registro central, pero solo decidir en tiempo de ejecución si conectar un registrador de archivos, stub logger, base de datos o message-queue logger.

+0

¿Qué haces? ¿Te refieres al servicio singleton? uno que solo tiene una instancia? – thecoshman

-1
  1. Singleton es un reemplazo muy útil de las variables globales, que se utiliza en todo el código.
  2. Singleton no suelen ser "nueva" ed o "Borrar" d, que tienden a ser inicializado en el primer uso y sean eliminados junto con el alcance del programa
  3. Singleton se adaptan perfectamente para envolver el registro, configuración y otras clases de hardware de interconexión .
+0

Los Singletons no son un buen reemplazo para las variables globales. Usados ​​incorrectamente, tienen todas las desventajas de las variables globales, y un par de extras para una buena medida. El único beneficio de singletons sobre globales es que las personas que no saben mejor se sienten bien consigo mismas porque en lugar de usar un sistema global (que saben que es malo, incluso si no saben por qué no), han utilizado un Diseño Patrón, que es una buena cosa (a pesar de que están recibiendo todos los problemas que tienen los globales). – kyoryu

+0

@kyoryu: un ataque ad hominem no es un buen argumento. Más bien sugiere una falta de buenos argumentos. –

+0

@Elise: No es un ad hominem. Los globales son malos por varias razones: vinculación estática con dependencias, estado mutable compartido y duración de la aplicación (lo que no es bueno). Singletons comparte todos esos aspectos. Los singletons, bien usados, son a) inmutables o b) implementan una interfaz y pasan a través de la inyección de dependencia. Los singletons no se usan comúnmente de esta manera, sino que se usan con más frecuencia como reemplazo de variables globales, sin resolver realmente los problemas fundamentales de los globales. – kyoryu

12

por las que se wa no a

yo no porque únicos generalmente son muy mala manera de resolver sus problemas.Mi recomendación para usted es evitarlos por completo.

Las principales razones son:

  • Singleton su mayoría representan el estado global (que es malo).
  • La inyección de dependencia correcta se vuelve imposible.

le sugiero que lea el resto (incluyendo explicaciones detalladas) en el blog de este empleado de Google:

+4

Hace cinco años implementé una política que dice: "Nunca use singletons. ¡Si está seguro de que necesita uno, convéncelo!". Lo desafiaron dos veces en cinco años. El resultado final fue siempre el mismo: La solución no única fue mejor. – Andreas

2

Al igual que los demás tener dijo:

  • Los singletons son variables globales con otro nombre.
  • Los singleton suelen ser una mala idea.
  • Singletons podría reemplazarse por clases "monostate" - clases que tienen una semántica de construcción/destrucción aparentemente normal, pero todas comparten el mismo estado.

Tenga en cuenta que en mi opinión "clases estáticas" son por lo general también una mala idea, una solución hacker para un lenguaje que no permite funciones gratuitas, o para compartir el estado entre un montón de funciones sin querer pasar ese estado como un parámetro.

En mi experiencia, casi todos los diseños con singletons o clases estáticas se pueden convertir en algo mejor, más fácil de entender y más flexible al deshacerse de esos constructos.

Editar: Por solicitud, por qué la mayoría de los singletons son variables globales con otro nombre.

En la mayoría de los idiomas que conozco, se accede a la mayoría de las clases de singleton a través de una función de miembro estático de esa clase. La instancia única está disponible para todos los códigos que tienen acceso a la definición de la clase singleton. Esta es una variable global: todo el código que incluye la clase podría hacer modificaciones a la única instancia de su singleton.
Si no usa la función de miembro estático (o algún método de fábrica estático que tenga las mismas implicaciones), sino que pase el objeto singleton a todos los clientes que lo necesitan, entonces no necesita el patrón singleton, simplemente pase el mismo objeto para todos los clientes.

+0

Puedo ver lo que quieres decir si tienes una clase que solo proporciona algunas funciones. Supongo que por "funciones gratuitas" te refieres a una función que acaba de declararse en cualquier lugar para su uso en cualquier lugar. Pero tener una clase que tenga una variable estática a la que todas las instancias puedan acceder, digamos in/de-crement como parte con/de-structor para que funcione como un contador de instancias puede ser muy 'limpia' especialmente cuando se combina con una función estática para obtener dicha variable, lo que le permite saber si tiene alguna pista perdida de una instancia. incluso podría extenderlo para permitirle regresar punteros a instancias, dejar que la clase rastree qué instancias existen – thecoshman

+1

Una clase que contiene cualquier funcionalidad no estática no es una clase estática; es una clase con miembros estáticos. Esto también suele ser motivo de preocupación en proyectos complejos, pero no es tan descabellado como una clase con SOLO datos estáticos y funciones de miembros. –

+0

¿Por qué dices que una clase con SOLO datos estáticos y funciones es 'hackish'? Sin duda, azotar un caballo muerto con este ejemplo ahora, tienes una clase de ayuda matemática, todo lo que necesitas son funciones. Y idiomas como C# no pueden tener funciones flotando, deben estar en una clase, a menos que los pegue en su clase principal, pero luego no pueden reutilizar el código tan fácilmente. – thecoshman

0

Además de las otras respuestas, tengo que decir que Singletons puede ayudarlo cuando quiere una clase estática, pero no puede tenerla, porque debido al diseño de su aplicación heredará una clase instanciable. .

2

Un poco de conocimiento es algo peligroso y los Singleton son entidades peligrosas. Además de las cosas escritas arriba, puedo enfatizar que la administración de por vida de los objetos de Singleton también es importante. En el marco de ACE, se maneja con éxito. Puede encontrar el documento aquí: http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf

Tenga en cuenta que los singletons deben ser clases no copiables.Este patrón puede parecer el más fácil, pero, por el contrario, es uno de los más difíciles. Por lo tanto, les pregunto a los candidatos sobre estos puntos malvados en Singletons.

0

Hay dos maneras de usar singletons.

  1. La forma en que se deben utilizar. Típicamente con variables inmutables (C# 's String.Empty, clases en Smalltalk, etc.). Esto es aproximadamente el 1% del uso de singleton.
  2. Como reemplazo de variables globales. Esto es malo. La causa principal de esto es la gente que quiere compartir objetos comunes sin entender cómo usar correctamente un generador. El uso de Singletons de esta manera es típicamente un signo de falta de comprensión profunda del diseño orientado a objetos.
Cuestiones relacionadas